18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * QLogic Fibre Channel HBA Driver 48c2ecf20Sopenharmony_ci * Copyright (c) 2003-2014 QLogic Corporation 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#include "qla_def.h" 78c2ecf20Sopenharmony_ci#include "qla_target.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include <linux/gfp.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 138c2ecf20Sopenharmony_ci#define IS_PPCARCH true 148c2ecf20Sopenharmony_ci#else 158c2ecf20Sopenharmony_ci#define IS_PPCARCH false 168c2ecf20Sopenharmony_ci#endif 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic struct mb_cmd_name { 198c2ecf20Sopenharmony_ci uint16_t cmd; 208c2ecf20Sopenharmony_ci const char *str; 218c2ecf20Sopenharmony_ci} mb_str[] = { 228c2ecf20Sopenharmony_ci {MBC_GET_PORT_DATABASE, "GPDB"}, 238c2ecf20Sopenharmony_ci {MBC_GET_ID_LIST, "GIDList"}, 248c2ecf20Sopenharmony_ci {MBC_GET_LINK_PRIV_STATS, "Stats"}, 258c2ecf20Sopenharmony_ci {MBC_GET_RESOURCE_COUNTS, "ResCnt"}, 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic const char *mb_to_str(uint16_t cmd) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci int i; 318c2ecf20Sopenharmony_ci struct mb_cmd_name *e; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mb_str); i++) { 348c2ecf20Sopenharmony_ci e = mb_str + i; 358c2ecf20Sopenharmony_ci if (cmd == e->cmd) 368c2ecf20Sopenharmony_ci return e->str; 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci return "unknown"; 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic struct rom_cmd { 428c2ecf20Sopenharmony_ci uint16_t cmd; 438c2ecf20Sopenharmony_ci} rom_cmds[] = { 448c2ecf20Sopenharmony_ci { MBC_LOAD_RAM }, 458c2ecf20Sopenharmony_ci { MBC_EXECUTE_FIRMWARE }, 468c2ecf20Sopenharmony_ci { MBC_READ_RAM_WORD }, 478c2ecf20Sopenharmony_ci { MBC_MAILBOX_REGISTER_TEST }, 488c2ecf20Sopenharmony_ci { MBC_VERIFY_CHECKSUM }, 498c2ecf20Sopenharmony_ci { MBC_GET_FIRMWARE_VERSION }, 508c2ecf20Sopenharmony_ci { MBC_LOAD_RISC_RAM }, 518c2ecf20Sopenharmony_ci { MBC_DUMP_RISC_RAM }, 528c2ecf20Sopenharmony_ci { MBC_LOAD_RISC_RAM_EXTENDED }, 538c2ecf20Sopenharmony_ci { MBC_DUMP_RISC_RAM_EXTENDED }, 548c2ecf20Sopenharmony_ci { MBC_WRITE_RAM_WORD_EXTENDED }, 558c2ecf20Sopenharmony_ci { MBC_READ_RAM_EXTENDED }, 568c2ecf20Sopenharmony_ci { MBC_GET_RESOURCE_COUNTS }, 578c2ecf20Sopenharmony_ci { MBC_SET_FIRMWARE_OPTION }, 588c2ecf20Sopenharmony_ci { MBC_MID_INITIALIZE_FIRMWARE }, 598c2ecf20Sopenharmony_ci { MBC_GET_FIRMWARE_STATE }, 608c2ecf20Sopenharmony_ci { MBC_GET_MEM_OFFLOAD_CNTRL_STAT }, 618c2ecf20Sopenharmony_ci { MBC_GET_RETRY_COUNT }, 628c2ecf20Sopenharmony_ci { MBC_TRACE_CONTROL }, 638c2ecf20Sopenharmony_ci { MBC_INITIALIZE_MULTIQ }, 648c2ecf20Sopenharmony_ci { MBC_IOCB_COMMAND_A64 }, 658c2ecf20Sopenharmony_ci { MBC_GET_ADAPTER_LOOP_ID }, 668c2ecf20Sopenharmony_ci { MBC_READ_SFP }, 678c2ecf20Sopenharmony_ci { MBC_SET_RNID_PARAMS }, 688c2ecf20Sopenharmony_ci { MBC_GET_RNID_PARAMS }, 698c2ecf20Sopenharmony_ci { MBC_GET_SET_ZIO_THRESHOLD }, 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int is_rom_cmd(uint16_t cmd) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci int i; 758c2ecf20Sopenharmony_ci struct rom_cmd *wc; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) { 788c2ecf20Sopenharmony_ci wc = rom_cmds + i; 798c2ecf20Sopenharmony_ci if (wc->cmd == cmd) 808c2ecf20Sopenharmony_ci return 1; 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci return 0; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* 878c2ecf20Sopenharmony_ci * qla2x00_mailbox_command 888c2ecf20Sopenharmony_ci * Issue mailbox command and waits for completion. 898c2ecf20Sopenharmony_ci * 908c2ecf20Sopenharmony_ci * Input: 918c2ecf20Sopenharmony_ci * ha = adapter block pointer. 928c2ecf20Sopenharmony_ci * mcp = driver internal mbx struct pointer. 938c2ecf20Sopenharmony_ci * 948c2ecf20Sopenharmony_ci * Output: 958c2ecf20Sopenharmony_ci * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data. 968c2ecf20Sopenharmony_ci * 978c2ecf20Sopenharmony_ci * Returns: 988c2ecf20Sopenharmony_ci * 0 : QLA_SUCCESS = cmd performed success 998c2ecf20Sopenharmony_ci * 1 : QLA_FUNCTION_FAILED (error encountered) 1008c2ecf20Sopenharmony_ci * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered) 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * Context: 1038c2ecf20Sopenharmony_ci * Kernel context. 1048c2ecf20Sopenharmony_ci */ 1058c2ecf20Sopenharmony_cistatic int 1068c2ecf20Sopenharmony_ciqla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci int rval, i; 1098c2ecf20Sopenharmony_ci unsigned long flags = 0; 1108c2ecf20Sopenharmony_ci device_reg_t *reg; 1118c2ecf20Sopenharmony_ci uint8_t abort_active; 1128c2ecf20Sopenharmony_ci uint8_t io_lock_on; 1138c2ecf20Sopenharmony_ci uint16_t command = 0; 1148c2ecf20Sopenharmony_ci uint16_t *iptr; 1158c2ecf20Sopenharmony_ci __le16 __iomem *optr; 1168c2ecf20Sopenharmony_ci uint32_t cnt; 1178c2ecf20Sopenharmony_ci uint32_t mboxes; 1188c2ecf20Sopenharmony_ci unsigned long wait_time; 1198c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 1208c2ecf20Sopenharmony_ci scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 1218c2ecf20Sopenharmony_ci u32 chip_reset; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci if (ha->pdev->error_state == pci_channel_io_perm_failure) { 1278c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1001, 1288c2ecf20Sopenharmony_ci "PCI channel failed permanently, exiting.\n"); 1298c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1308c2ecf20Sopenharmony_ci } 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (vha->device_flags & DFLG_DEV_FAILED) { 1338c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1002, 1348c2ecf20Sopenharmony_ci "Device in failed state, exiting.\n"); 1358c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* if PCI error, then avoid mbx processing.*/ 1398c2ecf20Sopenharmony_ci if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) && 1408c2ecf20Sopenharmony_ci test_bit(UNLOADING, &base_vha->dpc_flags)) { 1418c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd04e, 1428c2ecf20Sopenharmony_ci "PCI error, exiting.\n"); 1438c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci reg = ha->iobase; 1478c2ecf20Sopenharmony_ci io_lock_on = base_vha->flags.init_done; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 1508c2ecf20Sopenharmony_ci abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); 1518c2ecf20Sopenharmony_ci chip_reset = ha->chip_reset; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci if (ha->flags.pci_channel_io_perm_failure) { 1548c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1003, 1558c2ecf20Sopenharmony_ci "Perm failure on EEH timeout MBX, exiting.\n"); 1568c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) { 1608c2ecf20Sopenharmony_ci /* Setting Link-Down error */ 1618c2ecf20Sopenharmony_ci mcp->mb[0] = MBS_LINK_DOWN_ERROR; 1628c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1004, 1638c2ecf20Sopenharmony_ci "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); 1648c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1658c2ecf20Sopenharmony_ci } 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* check if ISP abort is active and return cmd with timeout */ 1688c2ecf20Sopenharmony_ci if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || 1698c2ecf20Sopenharmony_ci test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || 1708c2ecf20Sopenharmony_ci test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || 1718c2ecf20Sopenharmony_ci ha->flags.eeh_busy) && 1728c2ecf20Sopenharmony_ci !is_rom_cmd(mcp->mb[0])) { 1738c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x1005, 1748c2ecf20Sopenharmony_ci "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", 1758c2ecf20Sopenharmony_ci mcp->mb[0]); 1768c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci atomic_inc(&ha->num_pend_mbx_stage1); 1808c2ecf20Sopenharmony_ci /* 1818c2ecf20Sopenharmony_ci * Wait for active mailbox commands to finish by waiting at most tov 1828c2ecf20Sopenharmony_ci * seconds. This is to serialize actual issuing of mailbox cmds during 1838c2ecf20Sopenharmony_ci * non ISP abort time. 1848c2ecf20Sopenharmony_ci */ 1858c2ecf20Sopenharmony_ci if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) { 1868c2ecf20Sopenharmony_ci /* Timeout occurred. Return error. */ 1878c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd035, 1888c2ecf20Sopenharmony_ci "Cmd access timeout, cmd=0x%x, Exiting.\n", 1898c2ecf20Sopenharmony_ci mcp->mb[0]); 1908c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage1); 1918c2ecf20Sopenharmony_ci return QLA_FUNCTION_TIMEOUT; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage1); 1948c2ecf20Sopenharmony_ci if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { 1958c2ecf20Sopenharmony_ci rval = QLA_ABORTED; 1968c2ecf20Sopenharmony_ci goto premature_exit; 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* Save mailbox command for debug */ 2018c2ecf20Sopenharmony_ci ha->mcp = mcp; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1006, 2048c2ecf20Sopenharmony_ci "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || 2098c2ecf20Sopenharmony_ci ha->flags.mbox_busy) { 2108c2ecf20Sopenharmony_ci rval = QLA_ABORTED; 2118c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 2128c2ecf20Sopenharmony_ci goto premature_exit; 2138c2ecf20Sopenharmony_ci } 2148c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 1; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* Load mailbox registers. */ 2178c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha)) 2188c2ecf20Sopenharmony_ci optr = ®->isp82.mailbox_in[0]; 2198c2ecf20Sopenharmony_ci else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) 2208c2ecf20Sopenharmony_ci optr = ®->isp24.mailbox0; 2218c2ecf20Sopenharmony_ci else 2228c2ecf20Sopenharmony_ci optr = MAILBOX_REG(ha, ®->isp, 0); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci iptr = mcp->mb; 2258c2ecf20Sopenharmony_ci command = mcp->mb[0]; 2268c2ecf20Sopenharmony_ci mboxes = mcp->out_mb; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1111, 2298c2ecf20Sopenharmony_ci "Mailbox registers (OUT):\n"); 2308c2ecf20Sopenharmony_ci for (cnt = 0; cnt < ha->mbx_count; cnt++) { 2318c2ecf20Sopenharmony_ci if (IS_QLA2200(ha) && cnt == 8) 2328c2ecf20Sopenharmony_ci optr = MAILBOX_REG(ha, ®->isp, 8); 2338c2ecf20Sopenharmony_ci if (mboxes & BIT_0) { 2348c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1112, 2358c2ecf20Sopenharmony_ci "mbox[%d]<-0x%04x\n", cnt, *iptr); 2368c2ecf20Sopenharmony_ci wrt_reg_word(optr, *iptr); 2378c2ecf20Sopenharmony_ci } else { 2388c2ecf20Sopenharmony_ci wrt_reg_word(optr, 0); 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci mboxes >>= 1; 2428c2ecf20Sopenharmony_ci optr++; 2438c2ecf20Sopenharmony_ci iptr++; 2448c2ecf20Sopenharmony_ci } 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117, 2478c2ecf20Sopenharmony_ci "I/O Address = %p.\n", optr); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci /* Issue set host interrupt command to send cmd out. */ 2508c2ecf20Sopenharmony_ci ha->flags.mbox_int = 0; 2518c2ecf20Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci /* Unlock mbx registers and wait for interrupt */ 2548c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x100f, 2558c2ecf20Sopenharmony_ci "Going to unlock irq & waiting for interrupts. " 2568c2ecf20Sopenharmony_ci "jiffies=%lx.\n", jiffies); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci /* Wait for mbx cmd completion until timeout */ 2598c2ecf20Sopenharmony_ci atomic_inc(&ha->num_pend_mbx_stage2); 2608c2ecf20Sopenharmony_ci if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { 2618c2ecf20Sopenharmony_ci set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha)) 2648c2ecf20Sopenharmony_ci wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING); 2658c2ecf20Sopenharmony_ci else if (IS_FWI2_CAPABLE(ha)) 2668c2ecf20Sopenharmony_ci wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT); 2678c2ecf20Sopenharmony_ci else 2688c2ecf20Sopenharmony_ci wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT); 2698c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci wait_time = jiffies; 2728c2ecf20Sopenharmony_ci if (!wait_for_completion_timeout(&ha->mbx_intr_comp, 2738c2ecf20Sopenharmony_ci mcp->tov * HZ)) { 2748c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x117a, 2758c2ecf20Sopenharmony_ci "cmd=%x Timeout.\n", command); 2768c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 2778c2ecf20Sopenharmony_ci clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 2788c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (chip_reset != ha->chip_reset) { 2818c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 2828c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 2838c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, 2848c2ecf20Sopenharmony_ci flags); 2858c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage2); 2868c2ecf20Sopenharmony_ci rval = QLA_ABORTED; 2878c2ecf20Sopenharmony_ci goto premature_exit; 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci } else if (ha->flags.purge_mbox || 2908c2ecf20Sopenharmony_ci chip_reset != ha->chip_reset) { 2918c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 2928c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 2938c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 2948c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage2); 2958c2ecf20Sopenharmony_ci rval = QLA_ABORTED; 2968c2ecf20Sopenharmony_ci goto premature_exit; 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci if (time_after(jiffies, wait_time + 5 * HZ)) 3008c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", 3018c2ecf20Sopenharmony_ci command, jiffies_to_msecs(jiffies - wait_time)); 3028c2ecf20Sopenharmony_ci } else { 3038c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1011, 3048c2ecf20Sopenharmony_ci "Cmd=%x Polling Mode.\n", command); 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha)) { 3078c2ecf20Sopenharmony_ci if (rd_reg_dword(®->isp82.hint) & 3088c2ecf20Sopenharmony_ci HINT_MBX_INT_PENDING) { 3098c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 3108c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, 3118c2ecf20Sopenharmony_ci flags); 3128c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage2); 3138c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1012, 3148c2ecf20Sopenharmony_ci "Pending mailbox timeout, exiting.\n"); 3158c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 3168c2ecf20Sopenharmony_ci goto premature_exit; 3178c2ecf20Sopenharmony_ci } 3188c2ecf20Sopenharmony_ci wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING); 3198c2ecf20Sopenharmony_ci } else if (IS_FWI2_CAPABLE(ha)) 3208c2ecf20Sopenharmony_ci wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT); 3218c2ecf20Sopenharmony_ci else 3228c2ecf20Sopenharmony_ci wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT); 3238c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ 3268c2ecf20Sopenharmony_ci while (!ha->flags.mbox_int) { 3278c2ecf20Sopenharmony_ci if (ha->flags.purge_mbox || 3288c2ecf20Sopenharmony_ci chip_reset != ha->chip_reset) { 3298c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 3308c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 3318c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, 3328c2ecf20Sopenharmony_ci flags); 3338c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage2); 3348c2ecf20Sopenharmony_ci rval = QLA_ABORTED; 3358c2ecf20Sopenharmony_ci goto premature_exit; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (time_after(jiffies, wait_time)) 3398c2ecf20Sopenharmony_ci break; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci /* Check for pending interrupts. */ 3428c2ecf20Sopenharmony_ci qla2x00_poll(ha->rsp_q_map[0]); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci if (!ha->flags.mbox_int && 3458c2ecf20Sopenharmony_ci !(IS_QLA2200(ha) && 3468c2ecf20Sopenharmony_ci command == MBC_LOAD_RISC_RAM_EXTENDED)) 3478c2ecf20Sopenharmony_ci msleep(10); 3488c2ecf20Sopenharmony_ci } /* while */ 3498c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1013, 3508c2ecf20Sopenharmony_ci "Waited %d sec.\n", 3518c2ecf20Sopenharmony_ci (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ)); 3528c2ecf20Sopenharmony_ci } 3538c2ecf20Sopenharmony_ci atomic_dec(&ha->num_pend_mbx_stage2); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci /* Check whether we timed out */ 3568c2ecf20Sopenharmony_ci if (ha->flags.mbox_int) { 3578c2ecf20Sopenharmony_ci uint16_t *iptr2; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1014, 3608c2ecf20Sopenharmony_ci "Cmd=%x completed.\n", command); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* Got interrupt. Clear the flag. */ 3638c2ecf20Sopenharmony_ci ha->flags.mbox_int = 0; 3648c2ecf20Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) { 3678c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 3688c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 3698c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci /* Setting Link-Down error */ 3728c2ecf20Sopenharmony_ci mcp->mb[0] = MBS_LINK_DOWN_ERROR; 3738c2ecf20Sopenharmony_ci ha->mcp = NULL; 3748c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 3758c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd048, 3768c2ecf20Sopenharmony_ci "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); 3778c2ecf20Sopenharmony_ci goto premature_exit; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) { 3818c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x11ff, 3828c2ecf20Sopenharmony_ci "mb_out[0] = %#x <> %#x\n", ha->mailbox_out[0], 3838c2ecf20Sopenharmony_ci MBS_COMMAND_COMPLETE); 3848c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci /* Load return mailbox registers. */ 3888c2ecf20Sopenharmony_ci iptr2 = mcp->mb; 3898c2ecf20Sopenharmony_ci iptr = (uint16_t *)&ha->mailbox_out[0]; 3908c2ecf20Sopenharmony_ci mboxes = mcp->in_mb; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1113, 3938c2ecf20Sopenharmony_ci "Mailbox registers (IN):\n"); 3948c2ecf20Sopenharmony_ci for (cnt = 0; cnt < ha->mbx_count; cnt++) { 3958c2ecf20Sopenharmony_ci if (mboxes & BIT_0) { 3968c2ecf20Sopenharmony_ci *iptr2 = *iptr; 3978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1114, 3988c2ecf20Sopenharmony_ci "mbox[%d]->0x%04x\n", cnt, *iptr2); 3998c2ecf20Sopenharmony_ci } 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci mboxes >>= 1; 4028c2ecf20Sopenharmony_ci iptr2++; 4038c2ecf20Sopenharmony_ci iptr++; 4048c2ecf20Sopenharmony_ci } 4058c2ecf20Sopenharmony_ci } else { 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci uint16_t mb[8]; 4088c2ecf20Sopenharmony_ci uint32_t ictrl, host_status, hccr; 4098c2ecf20Sopenharmony_ci uint16_t w; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 4128c2ecf20Sopenharmony_ci mb[0] = rd_reg_word(®->isp24.mailbox0); 4138c2ecf20Sopenharmony_ci mb[1] = rd_reg_word(®->isp24.mailbox1); 4148c2ecf20Sopenharmony_ci mb[2] = rd_reg_word(®->isp24.mailbox2); 4158c2ecf20Sopenharmony_ci mb[3] = rd_reg_word(®->isp24.mailbox3); 4168c2ecf20Sopenharmony_ci mb[7] = rd_reg_word(®->isp24.mailbox7); 4178c2ecf20Sopenharmony_ci ictrl = rd_reg_dword(®->isp24.ictrl); 4188c2ecf20Sopenharmony_ci host_status = rd_reg_dword(®->isp24.host_status); 4198c2ecf20Sopenharmony_ci hccr = rd_reg_dword(®->isp24.hccr); 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd04c, 4228c2ecf20Sopenharmony_ci "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " 4238c2ecf20Sopenharmony_ci "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n", 4248c2ecf20Sopenharmony_ci command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3], 4258c2ecf20Sopenharmony_ci mb[7], host_status, hccr); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci } else { 4288c2ecf20Sopenharmony_ci mb[0] = RD_MAILBOX_REG(ha, ®->isp, 0); 4298c2ecf20Sopenharmony_ci ictrl = rd_reg_word(®->isp.ictrl); 4308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, 4318c2ecf20Sopenharmony_ci "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " 4328c2ecf20Sopenharmony_ci "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]); 4338c2ecf20Sopenharmony_ci } 4348c2ecf20Sopenharmony_ci ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci /* Capture FW dump only, if PCI device active */ 4378c2ecf20Sopenharmony_ci if (!pci_channel_offline(vha->hw->pdev)) { 4388c2ecf20Sopenharmony_ci pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 4398c2ecf20Sopenharmony_ci if (w == 0xffff || ictrl == 0xffffffff || 4408c2ecf20Sopenharmony_ci (chip_reset != ha->chip_reset)) { 4418c2ecf20Sopenharmony_ci /* This is special case if there is unload 4428c2ecf20Sopenharmony_ci * of driver happening and if PCI device go 4438c2ecf20Sopenharmony_ci * into bad state due to PCI error condition 4448c2ecf20Sopenharmony_ci * then only PCI ERR flag would be set. 4458c2ecf20Sopenharmony_ci * we will do premature exit for above case. 4468c2ecf20Sopenharmony_ci */ 4478c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 4488c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 4498c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, 4508c2ecf20Sopenharmony_ci flags); 4518c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 4528c2ecf20Sopenharmony_ci goto premature_exit; 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci /* Attempt to capture firmware dump for further 4568c2ecf20Sopenharmony_ci * anallysis of the current formware state. we do not 4578c2ecf20Sopenharmony_ci * need to do this if we are intentionally generating 4588c2ecf20Sopenharmony_ci * a dump 4598c2ecf20Sopenharmony_ci */ 4608c2ecf20Sopenharmony_ci if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) 4618c2ecf20Sopenharmony_ci qla2xxx_dump_fw(vha); 4628c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 4638c2ecf20Sopenharmony_ci } 4648c2ecf20Sopenharmony_ci } 4658c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 4668c2ecf20Sopenharmony_ci ha->flags.mbox_busy = 0; 4678c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci /* Clean up */ 4708c2ecf20Sopenharmony_ci ha->mcp = NULL; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) { 4738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x101a, 4748c2ecf20Sopenharmony_ci "Checking for additional resp interrupt.\n"); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci /* polling mode for non isp_abort commands. */ 4778c2ecf20Sopenharmony_ci qla2x00_poll(ha->rsp_q_map[0]); 4788c2ecf20Sopenharmony_ci } 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci if (rval == QLA_FUNCTION_TIMEOUT && 4818c2ecf20Sopenharmony_ci mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { 4828c2ecf20Sopenharmony_ci if (!io_lock_on || (mcp->flags & IOCTL_CMD) || 4838c2ecf20Sopenharmony_ci ha->flags.eeh_busy) { 4848c2ecf20Sopenharmony_ci /* not in dpc. schedule it for dpc to take over. */ 4858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x101b, 4868c2ecf20Sopenharmony_ci "Timeout, schedule isp_abort_needed.\n"); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && 4898c2ecf20Sopenharmony_ci !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && 4908c2ecf20Sopenharmony_ci !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { 4918c2ecf20Sopenharmony_ci if (IS_QLA82XX(ha)) { 4928c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x112a, 4938c2ecf20Sopenharmony_ci "disabling pause transmit on port " 4948c2ecf20Sopenharmony_ci "0 & 1.\n"); 4958c2ecf20Sopenharmony_ci qla82xx_wr_32(ha, 4968c2ecf20Sopenharmony_ci QLA82XX_CRB_NIU + 0x98, 4978c2ecf20Sopenharmony_ci CRB_NIU_XG_PAUSE_CTL_P0| 4988c2ecf20Sopenharmony_ci CRB_NIU_XG_PAUSE_CTL_P1); 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci ql_log(ql_log_info, base_vha, 0x101c, 5018c2ecf20Sopenharmony_ci "Mailbox cmd timeout occurred, cmd=0x%x, " 5028c2ecf20Sopenharmony_ci "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP " 5038c2ecf20Sopenharmony_ci "abort.\n", command, mcp->mb[0], 5048c2ecf20Sopenharmony_ci ha->flags.eeh_busy); 5058c2ecf20Sopenharmony_ci set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 5068c2ecf20Sopenharmony_ci qla2xxx_wake_dpc(vha); 5078c2ecf20Sopenharmony_ci } 5088c2ecf20Sopenharmony_ci } else if (current == ha->dpc_thread) { 5098c2ecf20Sopenharmony_ci /* call abort directly since we are in the DPC thread */ 5108c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x101d, 5118c2ecf20Sopenharmony_ci "Timeout, calling abort_isp.\n"); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && 5148c2ecf20Sopenharmony_ci !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && 5158c2ecf20Sopenharmony_ci !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { 5168c2ecf20Sopenharmony_ci if (IS_QLA82XX(ha)) { 5178c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x112b, 5188c2ecf20Sopenharmony_ci "disabling pause transmit on port " 5198c2ecf20Sopenharmony_ci "0 & 1.\n"); 5208c2ecf20Sopenharmony_ci qla82xx_wr_32(ha, 5218c2ecf20Sopenharmony_ci QLA82XX_CRB_NIU + 0x98, 5228c2ecf20Sopenharmony_ci CRB_NIU_XG_PAUSE_CTL_P0| 5238c2ecf20Sopenharmony_ci CRB_NIU_XG_PAUSE_CTL_P1); 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci ql_log(ql_log_info, base_vha, 0x101e, 5268c2ecf20Sopenharmony_ci "Mailbox cmd timeout occurred, cmd=0x%x, " 5278c2ecf20Sopenharmony_ci "mb[0]=0x%x. Scheduling ISP abort ", 5288c2ecf20Sopenharmony_ci command, mcp->mb[0]); 5298c2ecf20Sopenharmony_ci set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); 5308c2ecf20Sopenharmony_ci clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 5318c2ecf20Sopenharmony_ci /* Allow next mbx cmd to come in. */ 5328c2ecf20Sopenharmony_ci complete(&ha->mbx_cmd_comp); 5338c2ecf20Sopenharmony_ci if (ha->isp_ops->abort_isp(vha)) { 5348c2ecf20Sopenharmony_ci /* Failed. retry later. */ 5358c2ecf20Sopenharmony_ci set_bit(ISP_ABORT_NEEDED, 5368c2ecf20Sopenharmony_ci &vha->dpc_flags); 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); 5398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x101f, 5408c2ecf20Sopenharmony_ci "Finished abort_isp.\n"); 5418c2ecf20Sopenharmony_ci goto mbx_done; 5428c2ecf20Sopenharmony_ci } 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci } 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_cipremature_exit: 5478c2ecf20Sopenharmony_ci /* Allow next mbx cmd to come in. */ 5488c2ecf20Sopenharmony_ci complete(&ha->mbx_cmd_comp); 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cimbx_done: 5518c2ecf20Sopenharmony_ci if (rval == QLA_ABORTED) { 5528c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0xd035, 5538c2ecf20Sopenharmony_ci "Chip Reset in progress. Purging Mbox cmd=0x%x.\n", 5548c2ecf20Sopenharmony_ci mcp->mb[0]); 5558c2ecf20Sopenharmony_ci } else if (rval) { 5568c2ecf20Sopenharmony_ci if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { 5578c2ecf20Sopenharmony_ci pr_warn("%s [%s]-%04x:%ld: **** Failed=%x", QL_MSGHDR, 5588c2ecf20Sopenharmony_ci dev_name(&ha->pdev->dev), 0x1020+0x800, 5598c2ecf20Sopenharmony_ci vha->host_no, rval); 5608c2ecf20Sopenharmony_ci mboxes = mcp->in_mb; 5618c2ecf20Sopenharmony_ci cnt = 4; 5628c2ecf20Sopenharmony_ci for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1) 5638c2ecf20Sopenharmony_ci if (mboxes & BIT_0) { 5648c2ecf20Sopenharmony_ci printk(" mb[%u]=%x", i, mcp->mb[i]); 5658c2ecf20Sopenharmony_ci cnt--; 5668c2ecf20Sopenharmony_ci } 5678c2ecf20Sopenharmony_ci pr_warn(" cmd=%x ****\n", command); 5688c2ecf20Sopenharmony_ci } 5698c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) { 5708c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1198, 5718c2ecf20Sopenharmony_ci "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", 5728c2ecf20Sopenharmony_ci rd_reg_dword(®->isp24.host_status), 5738c2ecf20Sopenharmony_ci rd_reg_dword(®->isp24.ictrl), 5748c2ecf20Sopenharmony_ci rd_reg_dword(®->isp24.istatus)); 5758c2ecf20Sopenharmony_ci } else { 5768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1206, 5778c2ecf20Sopenharmony_ci "ctrl_status=%#x ictrl=%#x istatus=%#x\n", 5788c2ecf20Sopenharmony_ci rd_reg_word(®->isp.ctrl_status), 5798c2ecf20Sopenharmony_ci rd_reg_word(®->isp.ictrl), 5808c2ecf20Sopenharmony_ci rd_reg_word(®->isp.istatus)); 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci } else { 5838c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); 5848c2ecf20Sopenharmony_ci } 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci return rval; 5878c2ecf20Sopenharmony_ci} 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ciint 5908c2ecf20Sopenharmony_ciqla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, 5918c2ecf20Sopenharmony_ci uint32_t risc_code_size) 5928c2ecf20Sopenharmony_ci{ 5938c2ecf20Sopenharmony_ci int rval; 5948c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 5958c2ecf20Sopenharmony_ci mbx_cmd_t mc; 5968c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022, 5998c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) { 6028c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; 6038c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(risc_addr); 6048c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_0; 6058c2ecf20Sopenharmony_ci } else { 6068c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LOAD_RISC_RAM; 6078c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 6088c2ecf20Sopenharmony_ci } 6098c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(risc_addr); 6108c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(req_dma); 6118c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(req_dma); 6128c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(req_dma)); 6138c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(req_dma)); 6148c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; 6158c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 6168c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(risc_code_size); 6178c2ecf20Sopenharmony_ci mcp->mb[5] = LSW(risc_code_size); 6188c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_5|MBX_4; 6198c2ecf20Sopenharmony_ci } else { 6208c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(risc_code_size); 6218c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_4; 6228c2ecf20Sopenharmony_ci } 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 6258c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 6268c2ecf20Sopenharmony_ci mcp->flags = 0; 6278c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 6308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1023, 6318c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 6328c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 6338c2ecf20Sopenharmony_ci } else { 6348c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, 6358c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 6368c2ecf20Sopenharmony_ci } 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci return rval; 6398c2ecf20Sopenharmony_ci} 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci#define NVME_ENABLE_FLAG BIT_3 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci/* 6448c2ecf20Sopenharmony_ci * qla2x00_execute_fw 6458c2ecf20Sopenharmony_ci * Start adapter firmware. 6468c2ecf20Sopenharmony_ci * 6478c2ecf20Sopenharmony_ci * Input: 6488c2ecf20Sopenharmony_ci * ha = adapter block pointer. 6498c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 6508c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 6518c2ecf20Sopenharmony_ci * 6528c2ecf20Sopenharmony_ci * Returns: 6538c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 6548c2ecf20Sopenharmony_ci * 6558c2ecf20Sopenharmony_ci * Context: 6568c2ecf20Sopenharmony_ci * Kernel context. 6578c2ecf20Sopenharmony_ci */ 6588c2ecf20Sopenharmony_ciint 6598c2ecf20Sopenharmony_ciqla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) 6608c2ecf20Sopenharmony_ci{ 6618c2ecf20Sopenharmony_ci int rval; 6628c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 6638c2ecf20Sopenharmony_ci mbx_cmd_t mc; 6648c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 6658c2ecf20Sopenharmony_ci u8 semaphore = 0; 6668c2ecf20Sopenharmony_ci#define EXE_FW_FORCE_SEMAPHORE BIT_7 6678c2ecf20Sopenharmony_ci u8 retry = 3; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025, 6708c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ciagain: 6738c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 6748c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 6758c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 6768c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 6778c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(risc_addr); 6788c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(risc_addr); 6798c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 6808c2ecf20Sopenharmony_ci mcp->mb[4] = 0; 6818c2ecf20Sopenharmony_ci mcp->mb[11] = 0; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci /* Enable BPM? */ 6848c2ecf20Sopenharmony_ci if (ha->flags.lr_detected) { 6858c2ecf20Sopenharmony_ci mcp->mb[4] = BIT_0; 6868c2ecf20Sopenharmony_ci if (IS_BPM_RANGE_CAPABLE(ha)) 6878c2ecf20Sopenharmony_ci mcp->mb[4] |= 6888c2ecf20Sopenharmony_ci ha->lr_distance << LR_DIST_FW_POS; 6898c2ecf20Sopenharmony_ci } 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha))) 6928c2ecf20Sopenharmony_ci mcp->mb[4] |= NVME_ENABLE_FLAG; 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 6958c2ecf20Sopenharmony_ci struct nvram_81xx *nv = ha->nvram; 6968c2ecf20Sopenharmony_ci /* set minimum speed if specified in nvram */ 6978c2ecf20Sopenharmony_ci if (nv->min_supported_speed >= 2 && 6988c2ecf20Sopenharmony_ci nv->min_supported_speed <= 5) { 6998c2ecf20Sopenharmony_ci mcp->mb[4] |= BIT_4; 7008c2ecf20Sopenharmony_ci mcp->mb[11] |= nv->min_supported_speed & 0xF; 7018c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_11; 7028c2ecf20Sopenharmony_ci mcp->in_mb |= BIT_5; 7038c2ecf20Sopenharmony_ci vha->min_supported_speed = 7048c2ecf20Sopenharmony_ci nv->min_supported_speed; 7058c2ecf20Sopenharmony_ci } 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci if (IS_PPCARCH) 7088c2ecf20Sopenharmony_ci mcp->mb[11] |= BIT_4; 7098c2ecf20Sopenharmony_ci } 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci if (ha->flags.exlogins_enabled) 7128c2ecf20Sopenharmony_ci mcp->mb[4] |= ENABLE_EXTENDED_LOGIN; 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci if (ha->flags.exchoffld_enabled) 7158c2ecf20Sopenharmony_ci mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci if (semaphore) 7188c2ecf20Sopenharmony_ci mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11; 7218c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_3 | MBX_2 | MBX_1; 7228c2ecf20Sopenharmony_ci } else { 7238c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(risc_addr); 7248c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_1; 7258c2ecf20Sopenharmony_ci if (IS_QLA2322(ha) || IS_QLA6322(ha)) { 7268c2ecf20Sopenharmony_ci mcp->mb[2] = 0; 7278c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_2; 7288c2ecf20Sopenharmony_ci } 7298c2ecf20Sopenharmony_ci } 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 7328c2ecf20Sopenharmony_ci mcp->flags = 0; 7338c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 7368c2ecf20Sopenharmony_ci if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR && 7378c2ecf20Sopenharmony_ci mcp->mb[1] == 0x27 && retry) { 7388c2ecf20Sopenharmony_ci semaphore = 1; 7398c2ecf20Sopenharmony_ci retry--; 7408c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x1026, 7418c2ecf20Sopenharmony_ci "Exe FW: force semaphore.\n"); 7428c2ecf20Sopenharmony_ci goto again; 7438c2ecf20Sopenharmony_ci } 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1026, 7468c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 7478c2ecf20Sopenharmony_ci return rval; 7488c2ecf20Sopenharmony_ci } 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 7518c2ecf20Sopenharmony_ci goto done; 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2]; 7548c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119a, 7558c2ecf20Sopenharmony_ci "fw_ability_mask=%x.\n", ha->fw_ability_mask); 7568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1027, "exchanges=%x.\n", mcp->mb[1]); 7578c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 7588c2ecf20Sopenharmony_ci ha->max_supported_speed = mcp->mb[2] & (BIT_0|BIT_1); 7598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119b, "max_supported_speed=%s.\n", 7608c2ecf20Sopenharmony_ci ha->max_supported_speed == 0 ? "16Gps" : 7618c2ecf20Sopenharmony_ci ha->max_supported_speed == 1 ? "32Gps" : 7628c2ecf20Sopenharmony_ci ha->max_supported_speed == 2 ? "64Gps" : "unknown"); 7638c2ecf20Sopenharmony_ci if (vha->min_supported_speed) { 7648c2ecf20Sopenharmony_ci ha->min_supported_speed = mcp->mb[5] & 7658c2ecf20Sopenharmony_ci (BIT_0 | BIT_1 | BIT_2); 7668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119c, 7678c2ecf20Sopenharmony_ci "min_supported_speed=%s.\n", 7688c2ecf20Sopenharmony_ci ha->min_supported_speed == 6 ? "64Gps" : 7698c2ecf20Sopenharmony_ci ha->min_supported_speed == 5 ? "32Gps" : 7708c2ecf20Sopenharmony_ci ha->min_supported_speed == 4 ? "16Gps" : 7718c2ecf20Sopenharmony_ci ha->min_supported_speed == 3 ? "8Gps" : 7728c2ecf20Sopenharmony_ci ha->min_supported_speed == 2 ? "4Gps" : "unknown"); 7738c2ecf20Sopenharmony_ci } 7748c2ecf20Sopenharmony_ci } 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_cidone: 7778c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, 7788c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 7798c2ecf20Sopenharmony_ci 7808c2ecf20Sopenharmony_ci return rval; 7818c2ecf20Sopenharmony_ci} 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci/* 7848c2ecf20Sopenharmony_ci * qla_get_exlogin_status 7858c2ecf20Sopenharmony_ci * Get extended login status 7868c2ecf20Sopenharmony_ci * uses the memory offload control/status Mailbox 7878c2ecf20Sopenharmony_ci * 7888c2ecf20Sopenharmony_ci * Input: 7898c2ecf20Sopenharmony_ci * ha: adapter state pointer. 7908c2ecf20Sopenharmony_ci * fwopt: firmware options 7918c2ecf20Sopenharmony_ci * 7928c2ecf20Sopenharmony_ci * Returns: 7938c2ecf20Sopenharmony_ci * qla2x00 local function status 7948c2ecf20Sopenharmony_ci * 7958c2ecf20Sopenharmony_ci * Context: 7968c2ecf20Sopenharmony_ci * Kernel context. 7978c2ecf20Sopenharmony_ci */ 7988c2ecf20Sopenharmony_ci#define FETCH_XLOGINS_STAT 0x8 7998c2ecf20Sopenharmony_ciint 8008c2ecf20Sopenharmony_ciqla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz, 8018c2ecf20Sopenharmony_ci uint16_t *ex_logins_cnt) 8028c2ecf20Sopenharmony_ci{ 8038c2ecf20Sopenharmony_ci int rval; 8048c2ecf20Sopenharmony_ci mbx_cmd_t mc; 8058c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f, 8088c2ecf20Sopenharmony_ci "Entered %s\n", __func__); 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 8118c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 8128c2ecf20Sopenharmony_ci mcp->mb[1] = FETCH_XLOGINS_STAT; 8138c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 8148c2ecf20Sopenharmony_ci mcp->in_mb = MBX_10|MBX_4|MBX_0; 8158c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 8168c2ecf20Sopenharmony_ci mcp->flags = 0; 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 8198c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 8208c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval); 8218c2ecf20Sopenharmony_ci } else { 8228c2ecf20Sopenharmony_ci *buf_sz = mcp->mb[4]; 8238c2ecf20Sopenharmony_ci *ex_logins_cnt = mcp->mb[10]; 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x1190, 8268c2ecf20Sopenharmony_ci "buffer size 0x%x, exchange login count=%d\n", 8278c2ecf20Sopenharmony_ci mcp->mb[4], mcp->mb[10]); 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116, 8308c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 8318c2ecf20Sopenharmony_ci } 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci return rval; 8348c2ecf20Sopenharmony_ci} 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ci/* 8378c2ecf20Sopenharmony_ci * qla_set_exlogin_mem_cfg 8388c2ecf20Sopenharmony_ci * set extended login memory configuration 8398c2ecf20Sopenharmony_ci * Mbx needs to be issues before init_cb is set 8408c2ecf20Sopenharmony_ci * 8418c2ecf20Sopenharmony_ci * Input: 8428c2ecf20Sopenharmony_ci * ha: adapter state pointer. 8438c2ecf20Sopenharmony_ci * buffer: buffer pointer 8448c2ecf20Sopenharmony_ci * phys_addr: physical address of buffer 8458c2ecf20Sopenharmony_ci * size: size of buffer 8468c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released 8478c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be release 8488c2ecf20Sopenharmony_ci * 8498c2ecf20Sopenharmony_ci * Returns: 8508c2ecf20Sopenharmony_ci * qla2x00 local funxtion status code. 8518c2ecf20Sopenharmony_ci * 8528c2ecf20Sopenharmony_ci * Context: 8538c2ecf20Sopenharmony_ci * Kernel context. 8548c2ecf20Sopenharmony_ci */ 8558c2ecf20Sopenharmony_ci#define CONFIG_XLOGINS_MEM 0x9 8568c2ecf20Sopenharmony_ciint 8578c2ecf20Sopenharmony_ciqla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr) 8588c2ecf20Sopenharmony_ci{ 8598c2ecf20Sopenharmony_ci int rval; 8608c2ecf20Sopenharmony_ci mbx_cmd_t mc; 8618c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 8628c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a, 8658c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 8688c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 8698c2ecf20Sopenharmony_ci mcp->mb[1] = CONFIG_XLOGINS_MEM; 8708c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(phys_addr); 8718c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(phys_addr); 8728c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(phys_addr)); 8738c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(phys_addr)); 8748c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(ha->exlogin_size); 8758c2ecf20Sopenharmony_ci mcp->mb[9] = LSW(ha->exlogin_size); 8768c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 8778c2ecf20Sopenharmony_ci mcp->in_mb = MBX_11|MBX_0; 8788c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 8798c2ecf20Sopenharmony_ci mcp->flags = 0; 8808c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 8818c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 8828c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x111b, 8838c2ecf20Sopenharmony_ci "EXlogin Failed=%x. MB0=%x MB11=%x\n", 8848c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[11]); 8858c2ecf20Sopenharmony_ci } else { 8868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c, 8878c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 8888c2ecf20Sopenharmony_ci } 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ci return rval; 8918c2ecf20Sopenharmony_ci} 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci/* 8948c2ecf20Sopenharmony_ci * qla_get_exchoffld_status 8958c2ecf20Sopenharmony_ci * Get exchange offload status 8968c2ecf20Sopenharmony_ci * uses the memory offload control/status Mailbox 8978c2ecf20Sopenharmony_ci * 8988c2ecf20Sopenharmony_ci * Input: 8998c2ecf20Sopenharmony_ci * ha: adapter state pointer. 9008c2ecf20Sopenharmony_ci * fwopt: firmware options 9018c2ecf20Sopenharmony_ci * 9028c2ecf20Sopenharmony_ci * Returns: 9038c2ecf20Sopenharmony_ci * qla2x00 local function status 9048c2ecf20Sopenharmony_ci * 9058c2ecf20Sopenharmony_ci * Context: 9068c2ecf20Sopenharmony_ci * Kernel context. 9078c2ecf20Sopenharmony_ci */ 9088c2ecf20Sopenharmony_ci#define FETCH_XCHOFFLD_STAT 0x2 9098c2ecf20Sopenharmony_ciint 9108c2ecf20Sopenharmony_ciqla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz, 9118c2ecf20Sopenharmony_ci uint16_t *ex_logins_cnt) 9128c2ecf20Sopenharmony_ci{ 9138c2ecf20Sopenharmony_ci int rval; 9148c2ecf20Sopenharmony_ci mbx_cmd_t mc; 9158c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 9168c2ecf20Sopenharmony_ci 9178c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019, 9188c2ecf20Sopenharmony_ci "Entered %s\n", __func__); 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 9218c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 9228c2ecf20Sopenharmony_ci mcp->mb[1] = FETCH_XCHOFFLD_STAT; 9238c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 9248c2ecf20Sopenharmony_ci mcp->in_mb = MBX_10|MBX_4|MBX_0; 9258c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 9268c2ecf20Sopenharmony_ci mcp->flags = 0; 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 9298c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 9308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval); 9318c2ecf20Sopenharmony_ci } else { 9328c2ecf20Sopenharmony_ci *buf_sz = mcp->mb[4]; 9338c2ecf20Sopenharmony_ci *ex_logins_cnt = mcp->mb[10]; 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x118e, 9368c2ecf20Sopenharmony_ci "buffer size 0x%x, exchange offload count=%d\n", 9378c2ecf20Sopenharmony_ci mcp->mb[4], mcp->mb[10]); 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156, 9408c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 9418c2ecf20Sopenharmony_ci } 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci return rval; 9448c2ecf20Sopenharmony_ci} 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_ci/* 9478c2ecf20Sopenharmony_ci * qla_set_exchoffld_mem_cfg 9488c2ecf20Sopenharmony_ci * Set exchange offload memory configuration 9498c2ecf20Sopenharmony_ci * Mbx needs to be issues before init_cb is set 9508c2ecf20Sopenharmony_ci * 9518c2ecf20Sopenharmony_ci * Input: 9528c2ecf20Sopenharmony_ci * ha: adapter state pointer. 9538c2ecf20Sopenharmony_ci * buffer: buffer pointer 9548c2ecf20Sopenharmony_ci * phys_addr: physical address of buffer 9558c2ecf20Sopenharmony_ci * size: size of buffer 9568c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released 9578c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be release 9588c2ecf20Sopenharmony_ci * 9598c2ecf20Sopenharmony_ci * Returns: 9608c2ecf20Sopenharmony_ci * qla2x00 local funxtion status code. 9618c2ecf20Sopenharmony_ci * 9628c2ecf20Sopenharmony_ci * Context: 9638c2ecf20Sopenharmony_ci * Kernel context. 9648c2ecf20Sopenharmony_ci */ 9658c2ecf20Sopenharmony_ci#define CONFIG_XCHOFFLD_MEM 0x3 9668c2ecf20Sopenharmony_ciint 9678c2ecf20Sopenharmony_ciqla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha) 9688c2ecf20Sopenharmony_ci{ 9698c2ecf20Sopenharmony_ci int rval; 9708c2ecf20Sopenharmony_ci mbx_cmd_t mc; 9718c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 9728c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157, 9758c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 9788c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 9798c2ecf20Sopenharmony_ci mcp->mb[1] = CONFIG_XCHOFFLD_MEM; 9808c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(ha->exchoffld_buf_dma); 9818c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(ha->exchoffld_buf_dma); 9828c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma)); 9838c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma)); 9848c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(ha->exchoffld_size); 9858c2ecf20Sopenharmony_ci mcp->mb[9] = LSW(ha->exchoffld_size); 9868c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 9878c2ecf20Sopenharmony_ci mcp->in_mb = MBX_11|MBX_0; 9888c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 9898c2ecf20Sopenharmony_ci mcp->flags = 0; 9908c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 9918c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 9928c2ecf20Sopenharmony_ci /*EMPTY*/ 9938c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval); 9948c2ecf20Sopenharmony_ci } else { 9958c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192, 9968c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 9978c2ecf20Sopenharmony_ci } 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci return rval; 10008c2ecf20Sopenharmony_ci} 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci/* 10038c2ecf20Sopenharmony_ci * qla2x00_get_fw_version 10048c2ecf20Sopenharmony_ci * Get firmware version. 10058c2ecf20Sopenharmony_ci * 10068c2ecf20Sopenharmony_ci * Input: 10078c2ecf20Sopenharmony_ci * ha: adapter state pointer. 10088c2ecf20Sopenharmony_ci * major: pointer for major number. 10098c2ecf20Sopenharmony_ci * minor: pointer for minor number. 10108c2ecf20Sopenharmony_ci * subminor: pointer for subminor number. 10118c2ecf20Sopenharmony_ci * 10128c2ecf20Sopenharmony_ci * Returns: 10138c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 10148c2ecf20Sopenharmony_ci * 10158c2ecf20Sopenharmony_ci * Context: 10168c2ecf20Sopenharmony_ci * Kernel context. 10178c2ecf20Sopenharmony_ci */ 10188c2ecf20Sopenharmony_ciint 10198c2ecf20Sopenharmony_ciqla2x00_get_fw_version(scsi_qla_host_t *vha) 10208c2ecf20Sopenharmony_ci{ 10218c2ecf20Sopenharmony_ci int rval; 10228c2ecf20Sopenharmony_ci mbx_cmd_t mc; 10238c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 10248c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029, 10278c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; 10308c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 10318c2ecf20Sopenharmony_ci mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 10328c2ecf20Sopenharmony_ci if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha)) 10338c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; 10348c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) 10358c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_17|MBX_16|MBX_15; 10368c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) 10378c2ecf20Sopenharmony_ci mcp->in_mb |= 10388c2ecf20Sopenharmony_ci MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18| 10398c2ecf20Sopenharmony_ci MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7; 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci mcp->flags = 0; 10428c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 10438c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 10448c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) 10458c2ecf20Sopenharmony_ci goto failed; 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci /* Return mailbox data. */ 10488c2ecf20Sopenharmony_ci ha->fw_major_version = mcp->mb[1]; 10498c2ecf20Sopenharmony_ci ha->fw_minor_version = mcp->mb[2]; 10508c2ecf20Sopenharmony_ci ha->fw_subminor_version = mcp->mb[3]; 10518c2ecf20Sopenharmony_ci ha->fw_attributes = mcp->mb[6]; 10528c2ecf20Sopenharmony_ci if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw)) 10538c2ecf20Sopenharmony_ci ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */ 10548c2ecf20Sopenharmony_ci else 10558c2ecf20Sopenharmony_ci ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4]; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) { 10588c2ecf20Sopenharmony_ci ha->mpi_version[0] = mcp->mb[10] & 0xff; 10598c2ecf20Sopenharmony_ci ha->mpi_version[1] = mcp->mb[11] >> 8; 10608c2ecf20Sopenharmony_ci ha->mpi_version[2] = mcp->mb[11] & 0xff; 10618c2ecf20Sopenharmony_ci ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13]; 10628c2ecf20Sopenharmony_ci ha->phy_version[0] = mcp->mb[8] & 0xff; 10638c2ecf20Sopenharmony_ci ha->phy_version[1] = mcp->mb[9] >> 8; 10648c2ecf20Sopenharmony_ci ha->phy_version[2] = mcp->mb[9] & 0xff; 10658c2ecf20Sopenharmony_ci } 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 10688c2ecf20Sopenharmony_ci ha->fw_attributes_h = mcp->mb[15]; 10698c2ecf20Sopenharmony_ci ha->fw_attributes_ext[0] = mcp->mb[16]; 10708c2ecf20Sopenharmony_ci ha->fw_attributes_ext[1] = mcp->mb[17]; 10718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139, 10728c2ecf20Sopenharmony_ci "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n", 10738c2ecf20Sopenharmony_ci __func__, mcp->mb[15], mcp->mb[6]); 10748c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f, 10758c2ecf20Sopenharmony_ci "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n", 10768c2ecf20Sopenharmony_ci __func__, mcp->mb[17], mcp->mb[16]); 10778c2ecf20Sopenharmony_ci 10788c2ecf20Sopenharmony_ci if (ha->fw_attributes_h & 0x4) 10798c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d, 10808c2ecf20Sopenharmony_ci "%s: Firmware supports Extended Login 0x%x\n", 10818c2ecf20Sopenharmony_ci __func__, ha->fw_attributes_h); 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ci if (ha->fw_attributes_h & 0x8) 10848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191, 10858c2ecf20Sopenharmony_ci "%s: Firmware supports Exchange Offload 0x%x\n", 10868c2ecf20Sopenharmony_ci __func__, ha->fw_attributes_h); 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci /* 10898c2ecf20Sopenharmony_ci * FW supports nvme and driver load parameter requested nvme. 10908c2ecf20Sopenharmony_ci * BIT 26 of fw_attributes indicates NVMe support. 10918c2ecf20Sopenharmony_ci */ 10928c2ecf20Sopenharmony_ci if ((ha->fw_attributes_h & 10938c2ecf20Sopenharmony_ci (FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) && 10948c2ecf20Sopenharmony_ci ql2xnvmeenable) { 10958c2ecf20Sopenharmony_ci if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST) 10968c2ecf20Sopenharmony_ci vha->flags.nvme_first_burst = 1; 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_ci vha->flags.nvme_enabled = 1; 10998c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0xd302, 11008c2ecf20Sopenharmony_ci "%s: FC-NVMe is Enabled (0x%x)\n", 11018c2ecf20Sopenharmony_ci __func__, ha->fw_attributes_h); 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci /* BIT_13 of Extended FW Attributes informs about NVMe2 support */ 11058c2ecf20Sopenharmony_ci if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) { 11068c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0xd302, 11078c2ecf20Sopenharmony_ci "Firmware supports NVMe2 0x%x\n", 11088c2ecf20Sopenharmony_ci ha->fw_attributes_ext[0]); 11098c2ecf20Sopenharmony_ci vha->flags.nvme2_enabled = 1; 11108c2ecf20Sopenharmony_ci } 11118c2ecf20Sopenharmony_ci } 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 11148c2ecf20Sopenharmony_ci ha->serdes_version[0] = mcp->mb[7] & 0xff; 11158c2ecf20Sopenharmony_ci ha->serdes_version[1] = mcp->mb[8] >> 8; 11168c2ecf20Sopenharmony_ci ha->serdes_version[2] = mcp->mb[8] & 0xff; 11178c2ecf20Sopenharmony_ci ha->mpi_version[0] = mcp->mb[10] & 0xff; 11188c2ecf20Sopenharmony_ci ha->mpi_version[1] = mcp->mb[11] >> 8; 11198c2ecf20Sopenharmony_ci ha->mpi_version[2] = mcp->mb[11] & 0xff; 11208c2ecf20Sopenharmony_ci ha->pep_version[0] = mcp->mb[13] & 0xff; 11218c2ecf20Sopenharmony_ci ha->pep_version[1] = mcp->mb[14] >> 8; 11228c2ecf20Sopenharmony_ci ha->pep_version[2] = mcp->mb[14] & 0xff; 11238c2ecf20Sopenharmony_ci ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18]; 11248c2ecf20Sopenharmony_ci ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20]; 11258c2ecf20Sopenharmony_ci ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22]; 11268c2ecf20Sopenharmony_ci ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24]; 11278c2ecf20Sopenharmony_ci if (IS_QLA28XX(ha)) { 11288c2ecf20Sopenharmony_ci if (mcp->mb[16] & BIT_10) 11298c2ecf20Sopenharmony_ci ha->flags.secure_fw = 1; 11308c2ecf20Sopenharmony_ci 11318c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0xffff, 11328c2ecf20Sopenharmony_ci "Secure Flash Update in FW: %s\n", 11338c2ecf20Sopenharmony_ci (ha->flags.secure_fw) ? "Supported" : 11348c2ecf20Sopenharmony_ci "Not Supported"); 11358c2ecf20Sopenharmony_ci } 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_ci if (ha->flags.scm_supported_a && 11388c2ecf20Sopenharmony_ci (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) { 11398c2ecf20Sopenharmony_ci ha->flags.scm_supported_f = 1; 11408c2ecf20Sopenharmony_ci ha->sf_init_cb->flags |= cpu_to_le16(BIT_13); 11418c2ecf20Sopenharmony_ci } 11428c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n", 11438c2ecf20Sopenharmony_ci (ha->flags.scm_supported_f) ? "Supported" : 11448c2ecf20Sopenharmony_ci "Not Supported"); 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ci if (vha->flags.nvme2_enabled) { 11478c2ecf20Sopenharmony_ci /* set BIT_15 of special feature control block for SLER */ 11488c2ecf20Sopenharmony_ci ha->sf_init_cb->flags |= cpu_to_le16(BIT_15); 11498c2ecf20Sopenharmony_ci /* set BIT_14 of special feature control block for PI CTRL*/ 11508c2ecf20Sopenharmony_ci ha->sf_init_cb->flags |= cpu_to_le16(BIT_14); 11518c2ecf20Sopenharmony_ci } 11528c2ecf20Sopenharmony_ci } 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_cifailed: 11558c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 11568c2ecf20Sopenharmony_ci /*EMPTY*/ 11578c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval); 11588c2ecf20Sopenharmony_ci } else { 11598c2ecf20Sopenharmony_ci /*EMPTY*/ 11608c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b, 11618c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 11628c2ecf20Sopenharmony_ci } 11638c2ecf20Sopenharmony_ci return rval; 11648c2ecf20Sopenharmony_ci} 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci/* 11678c2ecf20Sopenharmony_ci * qla2x00_get_fw_options 11688c2ecf20Sopenharmony_ci * Set firmware options. 11698c2ecf20Sopenharmony_ci * 11708c2ecf20Sopenharmony_ci * Input: 11718c2ecf20Sopenharmony_ci * ha = adapter block pointer. 11728c2ecf20Sopenharmony_ci * fwopt = pointer for firmware options. 11738c2ecf20Sopenharmony_ci * 11748c2ecf20Sopenharmony_ci * Returns: 11758c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 11768c2ecf20Sopenharmony_ci * 11778c2ecf20Sopenharmony_ci * Context: 11788c2ecf20Sopenharmony_ci * Kernel context. 11798c2ecf20Sopenharmony_ci */ 11808c2ecf20Sopenharmony_ciint 11818c2ecf20Sopenharmony_ciqla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) 11828c2ecf20Sopenharmony_ci{ 11838c2ecf20Sopenharmony_ci int rval; 11848c2ecf20Sopenharmony_ci mbx_cmd_t mc; 11858c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c, 11888c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; 11918c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 11928c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 11938c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 11948c2ecf20Sopenharmony_ci mcp->flags = 0; 11958c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 11988c2ecf20Sopenharmony_ci /*EMPTY*/ 11998c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval); 12008c2ecf20Sopenharmony_ci } else { 12018c2ecf20Sopenharmony_ci fwopts[0] = mcp->mb[0]; 12028c2ecf20Sopenharmony_ci fwopts[1] = mcp->mb[1]; 12038c2ecf20Sopenharmony_ci fwopts[2] = mcp->mb[2]; 12048c2ecf20Sopenharmony_ci fwopts[3] = mcp->mb[3]; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e, 12078c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 12088c2ecf20Sopenharmony_ci } 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci return rval; 12118c2ecf20Sopenharmony_ci} 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci 12148c2ecf20Sopenharmony_ci/* 12158c2ecf20Sopenharmony_ci * qla2x00_set_fw_options 12168c2ecf20Sopenharmony_ci * Set firmware options. 12178c2ecf20Sopenharmony_ci * 12188c2ecf20Sopenharmony_ci * Input: 12198c2ecf20Sopenharmony_ci * ha = adapter block pointer. 12208c2ecf20Sopenharmony_ci * fwopt = pointer for firmware options. 12218c2ecf20Sopenharmony_ci * 12228c2ecf20Sopenharmony_ci * Returns: 12238c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 12248c2ecf20Sopenharmony_ci * 12258c2ecf20Sopenharmony_ci * Context: 12268c2ecf20Sopenharmony_ci * Kernel context. 12278c2ecf20Sopenharmony_ci */ 12288c2ecf20Sopenharmony_ciint 12298c2ecf20Sopenharmony_ciqla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) 12308c2ecf20Sopenharmony_ci{ 12318c2ecf20Sopenharmony_ci int rval; 12328c2ecf20Sopenharmony_ci mbx_cmd_t mc; 12338c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 12348c2ecf20Sopenharmony_ci 12358c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f, 12368c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_FIRMWARE_OPTION; 12398c2ecf20Sopenharmony_ci mcp->mb[1] = fwopts[1]; 12408c2ecf20Sopenharmony_ci mcp->mb[2] = fwopts[2]; 12418c2ecf20Sopenharmony_ci mcp->mb[3] = fwopts[3]; 12428c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 12438c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 12448c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) { 12458c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 12468c2ecf20Sopenharmony_ci mcp->mb[10] = fwopts[10]; 12478c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 12488c2ecf20Sopenharmony_ci } else { 12498c2ecf20Sopenharmony_ci mcp->mb[10] = fwopts[10]; 12508c2ecf20Sopenharmony_ci mcp->mb[11] = fwopts[11]; 12518c2ecf20Sopenharmony_ci mcp->mb[12] = 0; /* Undocumented, but used */ 12528c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_12|MBX_11|MBX_10; 12538c2ecf20Sopenharmony_ci } 12548c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 12558c2ecf20Sopenharmony_ci mcp->flags = 0; 12568c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ci fwopts[0] = mcp->mb[0]; 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 12618c2ecf20Sopenharmony_ci /*EMPTY*/ 12628c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1030, 12638c2ecf20Sopenharmony_ci "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]); 12648c2ecf20Sopenharmony_ci } else { 12658c2ecf20Sopenharmony_ci /*EMPTY*/ 12668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031, 12678c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 12688c2ecf20Sopenharmony_ci } 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci return rval; 12718c2ecf20Sopenharmony_ci} 12728c2ecf20Sopenharmony_ci 12738c2ecf20Sopenharmony_ci/* 12748c2ecf20Sopenharmony_ci * qla2x00_mbx_reg_test 12758c2ecf20Sopenharmony_ci * Mailbox register wrap test. 12768c2ecf20Sopenharmony_ci * 12778c2ecf20Sopenharmony_ci * Input: 12788c2ecf20Sopenharmony_ci * ha = adapter block pointer. 12798c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 12808c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 12818c2ecf20Sopenharmony_ci * 12828c2ecf20Sopenharmony_ci * Returns: 12838c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 12848c2ecf20Sopenharmony_ci * 12858c2ecf20Sopenharmony_ci * Context: 12868c2ecf20Sopenharmony_ci * Kernel context. 12878c2ecf20Sopenharmony_ci */ 12888c2ecf20Sopenharmony_ciint 12898c2ecf20Sopenharmony_ciqla2x00_mbx_reg_test(scsi_qla_host_t *vha) 12908c2ecf20Sopenharmony_ci{ 12918c2ecf20Sopenharmony_ci int rval; 12928c2ecf20Sopenharmony_ci mbx_cmd_t mc; 12938c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032, 12968c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 12978c2ecf20Sopenharmony_ci 12988c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 12998c2ecf20Sopenharmony_ci mcp->mb[1] = 0xAAAA; 13008c2ecf20Sopenharmony_ci mcp->mb[2] = 0x5555; 13018c2ecf20Sopenharmony_ci mcp->mb[3] = 0xAA55; 13028c2ecf20Sopenharmony_ci mcp->mb[4] = 0x55AA; 13038c2ecf20Sopenharmony_ci mcp->mb[5] = 0xA5A5; 13048c2ecf20Sopenharmony_ci mcp->mb[6] = 0x5A5A; 13058c2ecf20Sopenharmony_ci mcp->mb[7] = 0x2525; 13068c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 13078c2ecf20Sopenharmony_ci mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 13088c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 13098c2ecf20Sopenharmony_ci mcp->flags = 0; 13108c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) { 13138c2ecf20Sopenharmony_ci if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 || 13148c2ecf20Sopenharmony_ci mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) 13158c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 13168c2ecf20Sopenharmony_ci if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || 13178c2ecf20Sopenharmony_ci mcp->mb[7] != 0x2525) 13188c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 13198c2ecf20Sopenharmony_ci } 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 13228c2ecf20Sopenharmony_ci /*EMPTY*/ 13238c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval); 13248c2ecf20Sopenharmony_ci } else { 13258c2ecf20Sopenharmony_ci /*EMPTY*/ 13268c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034, 13278c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 13288c2ecf20Sopenharmony_ci } 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci return rval; 13318c2ecf20Sopenharmony_ci} 13328c2ecf20Sopenharmony_ci 13338c2ecf20Sopenharmony_ci/* 13348c2ecf20Sopenharmony_ci * qla2x00_verify_checksum 13358c2ecf20Sopenharmony_ci * Verify firmware checksum. 13368c2ecf20Sopenharmony_ci * 13378c2ecf20Sopenharmony_ci * Input: 13388c2ecf20Sopenharmony_ci * ha = adapter block pointer. 13398c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 13408c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 13418c2ecf20Sopenharmony_ci * 13428c2ecf20Sopenharmony_ci * Returns: 13438c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 13448c2ecf20Sopenharmony_ci * 13458c2ecf20Sopenharmony_ci * Context: 13468c2ecf20Sopenharmony_ci * Kernel context. 13478c2ecf20Sopenharmony_ci */ 13488c2ecf20Sopenharmony_ciint 13498c2ecf20Sopenharmony_ciqla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr) 13508c2ecf20Sopenharmony_ci{ 13518c2ecf20Sopenharmony_ci int rval; 13528c2ecf20Sopenharmony_ci mbx_cmd_t mc; 13538c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035, 13568c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 13578c2ecf20Sopenharmony_ci 13588c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_VERIFY_CHECKSUM; 13598c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 13608c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 13618c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) { 13628c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(risc_addr); 13638c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(risc_addr); 13648c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_2|MBX_1; 13658c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_2|MBX_1; 13668c2ecf20Sopenharmony_ci } else { 13678c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(risc_addr); 13688c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_1; 13698c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 13708c2ecf20Sopenharmony_ci } 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 13738c2ecf20Sopenharmony_ci mcp->flags = 0; 13748c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 13758c2ecf20Sopenharmony_ci 13768c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 13778c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1036, 13788c2ecf20Sopenharmony_ci "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ? 13798c2ecf20Sopenharmony_ci (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]); 13808c2ecf20Sopenharmony_ci } else { 13818c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037, 13828c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 13838c2ecf20Sopenharmony_ci } 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_ci return rval; 13868c2ecf20Sopenharmony_ci} 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci/* 13898c2ecf20Sopenharmony_ci * qla2x00_issue_iocb 13908c2ecf20Sopenharmony_ci * Issue IOCB using mailbox command 13918c2ecf20Sopenharmony_ci * 13928c2ecf20Sopenharmony_ci * Input: 13938c2ecf20Sopenharmony_ci * ha = adapter state pointer. 13948c2ecf20Sopenharmony_ci * buffer = buffer pointer. 13958c2ecf20Sopenharmony_ci * phys_addr = physical address of buffer. 13968c2ecf20Sopenharmony_ci * size = size of buffer. 13978c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 13988c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 13998c2ecf20Sopenharmony_ci * 14008c2ecf20Sopenharmony_ci * Returns: 14018c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 14028c2ecf20Sopenharmony_ci * 14038c2ecf20Sopenharmony_ci * Context: 14048c2ecf20Sopenharmony_ci * Kernel context. 14058c2ecf20Sopenharmony_ci */ 14068c2ecf20Sopenharmony_ciint 14078c2ecf20Sopenharmony_ciqla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer, 14088c2ecf20Sopenharmony_ci dma_addr_t phys_addr, size_t size, uint32_t tov) 14098c2ecf20Sopenharmony_ci{ 14108c2ecf20Sopenharmony_ci int rval; 14118c2ecf20Sopenharmony_ci mbx_cmd_t mc; 14128c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci if (!vha->hw->flags.fw_started) 14158c2ecf20Sopenharmony_ci return QLA_INVALID_COMMAND; 14168c2ecf20Sopenharmony_ci 14178c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038, 14188c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_IOCB_COMMAND_A64; 14218c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 14228c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(phys_addr)); 14238c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(phys_addr)); 14248c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(phys_addr)); 14258c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(phys_addr)); 14268c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 14278c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 14288c2ecf20Sopenharmony_ci mcp->tov = tov; 14298c2ecf20Sopenharmony_ci mcp->flags = 0; 14308c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 14338c2ecf20Sopenharmony_ci /*EMPTY*/ 14348c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval); 14358c2ecf20Sopenharmony_ci } else { 14368c2ecf20Sopenharmony_ci sts_entry_t *sts_entry = buffer; 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci /* Mask reserved bits. */ 14398c2ecf20Sopenharmony_ci sts_entry->entry_status &= 14408c2ecf20Sopenharmony_ci IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK; 14418c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a, 14428c2ecf20Sopenharmony_ci "Done %s (status=%x).\n", __func__, 14438c2ecf20Sopenharmony_ci sts_entry->entry_status); 14448c2ecf20Sopenharmony_ci } 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci return rval; 14478c2ecf20Sopenharmony_ci} 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ciint 14508c2ecf20Sopenharmony_ciqla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr, 14518c2ecf20Sopenharmony_ci size_t size) 14528c2ecf20Sopenharmony_ci{ 14538c2ecf20Sopenharmony_ci return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size, 14548c2ecf20Sopenharmony_ci MBX_TOV_SECONDS); 14558c2ecf20Sopenharmony_ci} 14568c2ecf20Sopenharmony_ci 14578c2ecf20Sopenharmony_ci/* 14588c2ecf20Sopenharmony_ci * qla2x00_abort_command 14598c2ecf20Sopenharmony_ci * Abort command aborts a specified IOCB. 14608c2ecf20Sopenharmony_ci * 14618c2ecf20Sopenharmony_ci * Input: 14628c2ecf20Sopenharmony_ci * ha = adapter block pointer. 14638c2ecf20Sopenharmony_ci * sp = SB structure pointer. 14648c2ecf20Sopenharmony_ci * 14658c2ecf20Sopenharmony_ci * Returns: 14668c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 14678c2ecf20Sopenharmony_ci * 14688c2ecf20Sopenharmony_ci * Context: 14698c2ecf20Sopenharmony_ci * Kernel context. 14708c2ecf20Sopenharmony_ci */ 14718c2ecf20Sopenharmony_ciint 14728c2ecf20Sopenharmony_ciqla2x00_abort_command(srb_t *sp) 14738c2ecf20Sopenharmony_ci{ 14748c2ecf20Sopenharmony_ci unsigned long flags = 0; 14758c2ecf20Sopenharmony_ci int rval; 14768c2ecf20Sopenharmony_ci uint32_t handle = 0; 14778c2ecf20Sopenharmony_ci mbx_cmd_t mc; 14788c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 14798c2ecf20Sopenharmony_ci fc_port_t *fcport = sp->fcport; 14808c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = fcport->vha; 14818c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 14828c2ecf20Sopenharmony_ci struct req_que *req; 14838c2ecf20Sopenharmony_ci struct scsi_cmnd *cmd = GET_CMD_SP(sp); 14848c2ecf20Sopenharmony_ci 14858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b, 14868c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci if (sp->qpair) 14898c2ecf20Sopenharmony_ci req = sp->qpair->req; 14908c2ecf20Sopenharmony_ci else 14918c2ecf20Sopenharmony_ci req = vha->req; 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 14948c2ecf20Sopenharmony_ci for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 14958c2ecf20Sopenharmony_ci if (req->outstanding_cmds[handle] == sp) 14968c2ecf20Sopenharmony_ci break; 14978c2ecf20Sopenharmony_ci } 14988c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci if (handle == req->num_outstanding_cmds) { 15018c2ecf20Sopenharmony_ci /* command not found */ 15028c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 15038c2ecf20Sopenharmony_ci } 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_ABORT_COMMAND; 15068c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(ha)) 15078c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 15088c2ecf20Sopenharmony_ci else 15098c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id << 8; 15108c2ecf20Sopenharmony_ci mcp->mb[2] = (uint16_t)handle; 15118c2ecf20Sopenharmony_ci mcp->mb[3] = (uint16_t)(handle >> 16); 15128c2ecf20Sopenharmony_ci mcp->mb[6] = (uint16_t)cmd->device->lun; 15138c2ecf20Sopenharmony_ci mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 15148c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 15158c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 15168c2ecf20Sopenharmony_ci mcp->flags = 0; 15178c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 15208c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval); 15218c2ecf20Sopenharmony_ci } else { 15228c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d, 15238c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 15248c2ecf20Sopenharmony_ci } 15258c2ecf20Sopenharmony_ci 15268c2ecf20Sopenharmony_ci return rval; 15278c2ecf20Sopenharmony_ci} 15288c2ecf20Sopenharmony_ci 15298c2ecf20Sopenharmony_ciint 15308c2ecf20Sopenharmony_ciqla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag) 15318c2ecf20Sopenharmony_ci{ 15328c2ecf20Sopenharmony_ci int rval, rval2; 15338c2ecf20Sopenharmony_ci mbx_cmd_t mc; 15348c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 15358c2ecf20Sopenharmony_ci scsi_qla_host_t *vha; 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_ci vha = fcport->vha; 15388c2ecf20Sopenharmony_ci 15398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e, 15408c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 15418c2ecf20Sopenharmony_ci 15428c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_ABORT_TARGET; 15438c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; 15448c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(vha->hw)) { 15458c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 15468c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 15478c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 15488c2ecf20Sopenharmony_ci } else { 15498c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id << 8; 15508c2ecf20Sopenharmony_ci } 15518c2ecf20Sopenharmony_ci mcp->mb[2] = vha->hw->loop_reset_delay; 15528c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 15538c2ecf20Sopenharmony_ci 15548c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 15558c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 15568c2ecf20Sopenharmony_ci mcp->flags = 0; 15578c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 15588c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 15598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f, 15608c2ecf20Sopenharmony_ci "Failed=%x.\n", rval); 15618c2ecf20Sopenharmony_ci } 15628c2ecf20Sopenharmony_ci 15638c2ecf20Sopenharmony_ci /* Issue marker IOCB. */ 15648c2ecf20Sopenharmony_ci rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, 0, 15658c2ecf20Sopenharmony_ci MK_SYNC_ID); 15668c2ecf20Sopenharmony_ci if (rval2 != QLA_SUCCESS) { 15678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1040, 15688c2ecf20Sopenharmony_ci "Failed to issue marker IOCB (%x).\n", rval2); 15698c2ecf20Sopenharmony_ci } else { 15708c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041, 15718c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 15728c2ecf20Sopenharmony_ci } 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci return rval; 15758c2ecf20Sopenharmony_ci} 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_ciint 15788c2ecf20Sopenharmony_ciqla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag) 15798c2ecf20Sopenharmony_ci{ 15808c2ecf20Sopenharmony_ci int rval, rval2; 15818c2ecf20Sopenharmony_ci mbx_cmd_t mc; 15828c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 15838c2ecf20Sopenharmony_ci scsi_qla_host_t *vha; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci vha = fcport->vha; 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042, 15888c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LUN_RESET; 15918c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 15928c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(vha->hw)) 15938c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 15948c2ecf20Sopenharmony_ci else 15958c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id << 8; 15968c2ecf20Sopenharmony_ci mcp->mb[2] = (u32)l; 15978c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 15988c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 15998c2ecf20Sopenharmony_ci 16008c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 16018c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 16028c2ecf20Sopenharmony_ci mcp->flags = 0; 16038c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 16048c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 16058c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval); 16068c2ecf20Sopenharmony_ci } 16078c2ecf20Sopenharmony_ci 16088c2ecf20Sopenharmony_ci /* Issue marker IOCB. */ 16098c2ecf20Sopenharmony_ci rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, l, 16108c2ecf20Sopenharmony_ci MK_SYNC_ID_LUN); 16118c2ecf20Sopenharmony_ci if (rval2 != QLA_SUCCESS) { 16128c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1044, 16138c2ecf20Sopenharmony_ci "Failed to issue marker IOCB (%x).\n", rval2); 16148c2ecf20Sopenharmony_ci } else { 16158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045, 16168c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 16178c2ecf20Sopenharmony_ci } 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_ci return rval; 16208c2ecf20Sopenharmony_ci} 16218c2ecf20Sopenharmony_ci 16228c2ecf20Sopenharmony_ci/* 16238c2ecf20Sopenharmony_ci * qla2x00_get_adapter_id 16248c2ecf20Sopenharmony_ci * Get adapter ID and topology. 16258c2ecf20Sopenharmony_ci * 16268c2ecf20Sopenharmony_ci * Input: 16278c2ecf20Sopenharmony_ci * ha = adapter block pointer. 16288c2ecf20Sopenharmony_ci * id = pointer for loop ID. 16298c2ecf20Sopenharmony_ci * al_pa = pointer for AL_PA. 16308c2ecf20Sopenharmony_ci * area = pointer for area. 16318c2ecf20Sopenharmony_ci * domain = pointer for domain. 16328c2ecf20Sopenharmony_ci * top = pointer for topology. 16338c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 16348c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 16358c2ecf20Sopenharmony_ci * 16368c2ecf20Sopenharmony_ci * Returns: 16378c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 16388c2ecf20Sopenharmony_ci * 16398c2ecf20Sopenharmony_ci * Context: 16408c2ecf20Sopenharmony_ci * Kernel context. 16418c2ecf20Sopenharmony_ci */ 16428c2ecf20Sopenharmony_ciint 16438c2ecf20Sopenharmony_ciqla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, 16448c2ecf20Sopenharmony_ci uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap) 16458c2ecf20Sopenharmony_ci{ 16468c2ecf20Sopenharmony_ci int rval; 16478c2ecf20Sopenharmony_ci mbx_cmd_t mc; 16488c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046, 16518c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; 16548c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 16558c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_0; 16568c2ecf20Sopenharmony_ci mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 16578c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(vha->hw)) 16588c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; 16598c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) 16608c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; 16618c2ecf20Sopenharmony_ci if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) 16628c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23; 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 16658c2ecf20Sopenharmony_ci mcp->flags = 0; 16668c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 16678c2ecf20Sopenharmony_ci if (mcp->mb[0] == MBS_COMMAND_ERROR) 16688c2ecf20Sopenharmony_ci rval = QLA_COMMAND_ERROR; 16698c2ecf20Sopenharmony_ci else if (mcp->mb[0] == MBS_INVALID_COMMAND) 16708c2ecf20Sopenharmony_ci rval = QLA_INVALID_COMMAND; 16718c2ecf20Sopenharmony_ci 16728c2ecf20Sopenharmony_ci /* Return data. */ 16738c2ecf20Sopenharmony_ci *id = mcp->mb[1]; 16748c2ecf20Sopenharmony_ci *al_pa = LSB(mcp->mb[2]); 16758c2ecf20Sopenharmony_ci *area = MSB(mcp->mb[2]); 16768c2ecf20Sopenharmony_ci *domain = LSB(mcp->mb[3]); 16778c2ecf20Sopenharmony_ci *top = mcp->mb[6]; 16788c2ecf20Sopenharmony_ci *sw_cap = mcp->mb[7]; 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 16818c2ecf20Sopenharmony_ci /*EMPTY*/ 16828c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval); 16838c2ecf20Sopenharmony_ci } else { 16848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048, 16858c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(vha->hw)) { 16888c2ecf20Sopenharmony_ci vha->fcoe_vlan_id = mcp->mb[9] & 0xfff; 16898c2ecf20Sopenharmony_ci vha->fcoe_fcf_idx = mcp->mb[10]; 16908c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8; 16918c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff; 16928c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8; 16938c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff; 16948c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8; 16958c2ecf20Sopenharmony_ci vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff; 16968c2ecf20Sopenharmony_ci } 16978c2ecf20Sopenharmony_ci /* If FA-WWN supported */ 16988c2ecf20Sopenharmony_ci if (IS_FAWWN_CAPABLE(vha->hw)) { 16998c2ecf20Sopenharmony_ci if (mcp->mb[7] & BIT_14) { 17008c2ecf20Sopenharmony_ci vha->port_name[0] = MSB(mcp->mb[16]); 17018c2ecf20Sopenharmony_ci vha->port_name[1] = LSB(mcp->mb[16]); 17028c2ecf20Sopenharmony_ci vha->port_name[2] = MSB(mcp->mb[17]); 17038c2ecf20Sopenharmony_ci vha->port_name[3] = LSB(mcp->mb[17]); 17048c2ecf20Sopenharmony_ci vha->port_name[4] = MSB(mcp->mb[18]); 17058c2ecf20Sopenharmony_ci vha->port_name[5] = LSB(mcp->mb[18]); 17068c2ecf20Sopenharmony_ci vha->port_name[6] = MSB(mcp->mb[19]); 17078c2ecf20Sopenharmony_ci vha->port_name[7] = LSB(mcp->mb[19]); 17088c2ecf20Sopenharmony_ci fc_host_port_name(vha->host) = 17098c2ecf20Sopenharmony_ci wwn_to_u64(vha->port_name); 17108c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ca, 17118c2ecf20Sopenharmony_ci "FA-WWN acquired %016llx\n", 17128c2ecf20Sopenharmony_ci wwn_to_u64(vha->port_name)); 17138c2ecf20Sopenharmony_ci } 17148c2ecf20Sopenharmony_ci } 17158c2ecf20Sopenharmony_ci 17168c2ecf20Sopenharmony_ci if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) { 17178c2ecf20Sopenharmony_ci vha->bbcr = mcp->mb[15]; 17188c2ecf20Sopenharmony_ci if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) { 17198c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x11a4, 17208c2ecf20Sopenharmony_ci "SCM: EDC ELS completed, flags 0x%x\n", 17218c2ecf20Sopenharmony_ci mcp->mb[21]); 17228c2ecf20Sopenharmony_ci } 17238c2ecf20Sopenharmony_ci if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) { 17248c2ecf20Sopenharmony_ci vha->hw->flags.scm_enabled = 1; 17258c2ecf20Sopenharmony_ci vha->scm_fabric_connection_flags |= 17268c2ecf20Sopenharmony_ci SCM_FLAG_RDF_COMPLETED; 17278c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x11a5, 17288c2ecf20Sopenharmony_ci "SCM: RDF ELS completed, flags 0x%x\n", 17298c2ecf20Sopenharmony_ci mcp->mb[23]); 17308c2ecf20Sopenharmony_ci } 17318c2ecf20Sopenharmony_ci } 17328c2ecf20Sopenharmony_ci } 17338c2ecf20Sopenharmony_ci 17348c2ecf20Sopenharmony_ci return rval; 17358c2ecf20Sopenharmony_ci} 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_ci/* 17388c2ecf20Sopenharmony_ci * qla2x00_get_retry_cnt 17398c2ecf20Sopenharmony_ci * Get current firmware login retry count and delay. 17408c2ecf20Sopenharmony_ci * 17418c2ecf20Sopenharmony_ci * Input: 17428c2ecf20Sopenharmony_ci * ha = adapter block pointer. 17438c2ecf20Sopenharmony_ci * retry_cnt = pointer to login retry count. 17448c2ecf20Sopenharmony_ci * tov = pointer to login timeout value. 17458c2ecf20Sopenharmony_ci * 17468c2ecf20Sopenharmony_ci * Returns: 17478c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 17488c2ecf20Sopenharmony_ci * 17498c2ecf20Sopenharmony_ci * Context: 17508c2ecf20Sopenharmony_ci * Kernel context. 17518c2ecf20Sopenharmony_ci */ 17528c2ecf20Sopenharmony_ciint 17538c2ecf20Sopenharmony_ciqla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov, 17548c2ecf20Sopenharmony_ci uint16_t *r_a_tov) 17558c2ecf20Sopenharmony_ci{ 17568c2ecf20Sopenharmony_ci int rval; 17578c2ecf20Sopenharmony_ci uint16_t ratov; 17588c2ecf20Sopenharmony_ci mbx_cmd_t mc; 17598c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 17608c2ecf20Sopenharmony_ci 17618c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049, 17628c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 17638c2ecf20Sopenharmony_ci 17648c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_RETRY_COUNT; 17658c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 17668c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 17678c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 17688c2ecf20Sopenharmony_ci mcp->flags = 0; 17698c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 17708c2ecf20Sopenharmony_ci 17718c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 17728c2ecf20Sopenharmony_ci /*EMPTY*/ 17738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x104a, 17748c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 17758c2ecf20Sopenharmony_ci } else { 17768c2ecf20Sopenharmony_ci /* Convert returned data and check our values. */ 17778c2ecf20Sopenharmony_ci *r_a_tov = mcp->mb[3] / 2; 17788c2ecf20Sopenharmony_ci ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */ 17798c2ecf20Sopenharmony_ci if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) { 17808c2ecf20Sopenharmony_ci /* Update to the larger values */ 17818c2ecf20Sopenharmony_ci *retry_cnt = (uint8_t)mcp->mb[1]; 17828c2ecf20Sopenharmony_ci *tov = ratov; 17838c2ecf20Sopenharmony_ci } 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b, 17868c2ecf20Sopenharmony_ci "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov); 17878c2ecf20Sopenharmony_ci } 17888c2ecf20Sopenharmony_ci 17898c2ecf20Sopenharmony_ci return rval; 17908c2ecf20Sopenharmony_ci} 17918c2ecf20Sopenharmony_ci 17928c2ecf20Sopenharmony_ci/* 17938c2ecf20Sopenharmony_ci * qla2x00_init_firmware 17948c2ecf20Sopenharmony_ci * Initialize adapter firmware. 17958c2ecf20Sopenharmony_ci * 17968c2ecf20Sopenharmony_ci * Input: 17978c2ecf20Sopenharmony_ci * ha = adapter block pointer. 17988c2ecf20Sopenharmony_ci * dptr = Initialization control block pointer. 17998c2ecf20Sopenharmony_ci * size = size of initialization control block. 18008c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 18018c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 18028c2ecf20Sopenharmony_ci * 18038c2ecf20Sopenharmony_ci * Returns: 18048c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 18058c2ecf20Sopenharmony_ci * 18068c2ecf20Sopenharmony_ci * Context: 18078c2ecf20Sopenharmony_ci * Kernel context. 18088c2ecf20Sopenharmony_ci */ 18098c2ecf20Sopenharmony_ciint 18108c2ecf20Sopenharmony_ciqla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) 18118c2ecf20Sopenharmony_ci{ 18128c2ecf20Sopenharmony_ci int rval; 18138c2ecf20Sopenharmony_ci mbx_cmd_t mc; 18148c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 18158c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c, 18188c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci if (IS_P3P_TYPE(ha) && ql2xdbwr) 18218c2ecf20Sopenharmony_ci qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr, 18228c2ecf20Sopenharmony_ci (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16))); 18238c2ecf20Sopenharmony_ci 18248c2ecf20Sopenharmony_ci if (ha->flags.npiv_supported) 18258c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE; 18268c2ecf20Sopenharmony_ci else 18278c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 18308c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(ha->init_cb_dma); 18318c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(ha->init_cb_dma); 18328c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(ha->init_cb_dma)); 18338c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(ha->init_cb_dma)); 18348c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 18358c2ecf20Sopenharmony_ci if (ha->ex_init_cb && ha->ex_init_cb->ex_version) { 18368c2ecf20Sopenharmony_ci mcp->mb[1] = BIT_0; 18378c2ecf20Sopenharmony_ci mcp->mb[10] = MSW(ha->ex_init_cb_dma); 18388c2ecf20Sopenharmony_ci mcp->mb[11] = LSW(ha->ex_init_cb_dma); 18398c2ecf20Sopenharmony_ci mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma)); 18408c2ecf20Sopenharmony_ci mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma)); 18418c2ecf20Sopenharmony_ci mcp->mb[14] = sizeof(*ha->ex_init_cb); 18428c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10; 18438c2ecf20Sopenharmony_ci } 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) { 18468c2ecf20Sopenharmony_ci mcp->mb[1] |= BIT_1; 18478c2ecf20Sopenharmony_ci mcp->mb[16] = MSW(ha->sf_init_cb_dma); 18488c2ecf20Sopenharmony_ci mcp->mb[17] = LSW(ha->sf_init_cb_dma); 18498c2ecf20Sopenharmony_ci mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma)); 18508c2ecf20Sopenharmony_ci mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma)); 18518c2ecf20Sopenharmony_ci mcp->mb[15] = sizeof(*ha->sf_init_cb); 18528c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15; 18538c2ecf20Sopenharmony_ci } 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_ci /* 1 and 2 should normally be captured. */ 18568c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 18578c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 18588c2ecf20Sopenharmony_ci /* mb3 is additional info about the installed SFP. */ 18598c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_3; 18608c2ecf20Sopenharmony_ci mcp->buf_size = size; 18618c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT; 18628c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 18638c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 18668c2ecf20Sopenharmony_ci /*EMPTY*/ 18678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x104d, 18688c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x.\n", 18698c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); 18708c2ecf20Sopenharmony_ci if (ha->init_cb) { 18718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x104d, "init_cb:\n"); 18728c2ecf20Sopenharmony_ci ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 18738c2ecf20Sopenharmony_ci 0x0104d, ha->init_cb, sizeof(*ha->init_cb)); 18748c2ecf20Sopenharmony_ci } 18758c2ecf20Sopenharmony_ci if (ha->ex_init_cb && ha->ex_init_cb->ex_version) { 18768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x104d, "ex_init_cb:\n"); 18778c2ecf20Sopenharmony_ci ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 18788c2ecf20Sopenharmony_ci 0x0104d, ha->ex_init_cb, sizeof(*ha->ex_init_cb)); 18798c2ecf20Sopenharmony_ci } 18808c2ecf20Sopenharmony_ci } else { 18818c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 18828c2ecf20Sopenharmony_ci if (mcp->mb[2] == 6 || mcp->mb[3] == 2) 18838c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119d, 18848c2ecf20Sopenharmony_ci "Invalid SFP/Validation Failed\n"); 18858c2ecf20Sopenharmony_ci } 18868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e, 18878c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 18888c2ecf20Sopenharmony_ci } 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_ci return rval; 18918c2ecf20Sopenharmony_ci} 18928c2ecf20Sopenharmony_ci 18938c2ecf20Sopenharmony_ci 18948c2ecf20Sopenharmony_ci/* 18958c2ecf20Sopenharmony_ci * qla2x00_get_port_database 18968c2ecf20Sopenharmony_ci * Issue normal/enhanced get port database mailbox command 18978c2ecf20Sopenharmony_ci * and copy device name as necessary. 18988c2ecf20Sopenharmony_ci * 18998c2ecf20Sopenharmony_ci * Input: 19008c2ecf20Sopenharmony_ci * ha = adapter state pointer. 19018c2ecf20Sopenharmony_ci * dev = structure pointer. 19028c2ecf20Sopenharmony_ci * opt = enhanced cmd option byte. 19038c2ecf20Sopenharmony_ci * 19048c2ecf20Sopenharmony_ci * Returns: 19058c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 19068c2ecf20Sopenharmony_ci * 19078c2ecf20Sopenharmony_ci * Context: 19088c2ecf20Sopenharmony_ci * Kernel context. 19098c2ecf20Sopenharmony_ci */ 19108c2ecf20Sopenharmony_ciint 19118c2ecf20Sopenharmony_ciqla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) 19128c2ecf20Sopenharmony_ci{ 19138c2ecf20Sopenharmony_ci int rval; 19148c2ecf20Sopenharmony_ci mbx_cmd_t mc; 19158c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 19168c2ecf20Sopenharmony_ci port_database_t *pd; 19178c2ecf20Sopenharmony_ci struct port_database_24xx *pd24; 19188c2ecf20Sopenharmony_ci dma_addr_t pd_dma; 19198c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 19208c2ecf20Sopenharmony_ci 19218c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f, 19228c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 19238c2ecf20Sopenharmony_ci 19248c2ecf20Sopenharmony_ci pd24 = NULL; 19258c2ecf20Sopenharmony_ci pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 19268c2ecf20Sopenharmony_ci if (pd == NULL) { 19278c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1050, 19288c2ecf20Sopenharmony_ci "Failed to allocate port database structure.\n"); 19298c2ecf20Sopenharmony_ci fcport->query = 0; 19308c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 19318c2ecf20Sopenharmony_ci } 19328c2ecf20Sopenharmony_ci 19338c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_PORT_DATABASE; 19348c2ecf20Sopenharmony_ci if (opt != 0 && !IS_FWI2_CAPABLE(ha)) 19358c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; 19368c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(pd_dma); 19378c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(pd_dma); 19388c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(pd_dma)); 19398c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(pd_dma)); 19408c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 19418c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 19428c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 19438c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 19448c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 19458c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 19468c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10|MBX_1; 19478c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 19488c2ecf20Sopenharmony_ci } else if (HAS_EXTENDED_IDS(ha)) { 19498c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 19508c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 19518c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10|MBX_1; 19528c2ecf20Sopenharmony_ci } else { 19538c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id << 8 | opt; 19548c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_1; 19558c2ecf20Sopenharmony_ci } 19568c2ecf20Sopenharmony_ci mcp->buf_size = IS_FWI2_CAPABLE(ha) ? 19578c2ecf20Sopenharmony_ci PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE; 19588c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_IN; 19598c2ecf20Sopenharmony_ci mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 19608c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 19618c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) 19628c2ecf20Sopenharmony_ci goto gpd_error_out; 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 19658c2ecf20Sopenharmony_ci uint64_t zero = 0; 19668c2ecf20Sopenharmony_ci u8 current_login_state, last_login_state; 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_ci pd24 = (struct port_database_24xx *) pd; 19698c2ecf20Sopenharmony_ci 19708c2ecf20Sopenharmony_ci /* Check for logged in state. */ 19718c2ecf20Sopenharmony_ci if (NVME_TARGET(ha, fcport)) { 19728c2ecf20Sopenharmony_ci current_login_state = pd24->current_login_state >> 4; 19738c2ecf20Sopenharmony_ci last_login_state = pd24->last_login_state >> 4; 19748c2ecf20Sopenharmony_ci } else { 19758c2ecf20Sopenharmony_ci current_login_state = pd24->current_login_state & 0xf; 19768c2ecf20Sopenharmony_ci last_login_state = pd24->last_login_state & 0xf; 19778c2ecf20Sopenharmony_ci } 19788c2ecf20Sopenharmony_ci fcport->current_login_state = pd24->current_login_state; 19798c2ecf20Sopenharmony_ci fcport->last_login_state = pd24->last_login_state; 19808c2ecf20Sopenharmony_ci 19818c2ecf20Sopenharmony_ci /* Check for logged in state. */ 19828c2ecf20Sopenharmony_ci if (current_login_state != PDS_PRLI_COMPLETE && 19838c2ecf20Sopenharmony_ci last_login_state != PDS_PRLI_COMPLETE) { 19848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119a, 19858c2ecf20Sopenharmony_ci "Unable to verify login-state (%x/%x) for loop_id %x.\n", 19868c2ecf20Sopenharmony_ci current_login_state, last_login_state, 19878c2ecf20Sopenharmony_ci fcport->loop_id); 19888c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_ci if (!fcport->query) 19918c2ecf20Sopenharmony_ci goto gpd_error_out; 19928c2ecf20Sopenharmony_ci } 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci if (fcport->loop_id == FC_NO_LOOP_ID || 19958c2ecf20Sopenharmony_ci (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 19968c2ecf20Sopenharmony_ci memcmp(fcport->port_name, pd24->port_name, 8))) { 19978c2ecf20Sopenharmony_ci /* We lost the device mid way. */ 19988c2ecf20Sopenharmony_ci rval = QLA_NOT_LOGGED_IN; 19998c2ecf20Sopenharmony_ci goto gpd_error_out; 20008c2ecf20Sopenharmony_ci } 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci /* Names are little-endian. */ 20038c2ecf20Sopenharmony_ci memcpy(fcport->node_name, pd24->node_name, WWN_SIZE); 20048c2ecf20Sopenharmony_ci memcpy(fcport->port_name, pd24->port_name, WWN_SIZE); 20058c2ecf20Sopenharmony_ci 20068c2ecf20Sopenharmony_ci /* Get port_id of device. */ 20078c2ecf20Sopenharmony_ci fcport->d_id.b.domain = pd24->port_id[0]; 20088c2ecf20Sopenharmony_ci fcport->d_id.b.area = pd24->port_id[1]; 20098c2ecf20Sopenharmony_ci fcport->d_id.b.al_pa = pd24->port_id[2]; 20108c2ecf20Sopenharmony_ci fcport->d_id.b.rsvd_1 = 0; 20118c2ecf20Sopenharmony_ci 20128c2ecf20Sopenharmony_ci /* If not target must be initiator or unknown type. */ 20138c2ecf20Sopenharmony_ci if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0) 20148c2ecf20Sopenharmony_ci fcport->port_type = FCT_INITIATOR; 20158c2ecf20Sopenharmony_ci else 20168c2ecf20Sopenharmony_ci fcport->port_type = FCT_TARGET; 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci /* Passback COS information. */ 20198c2ecf20Sopenharmony_ci fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ? 20208c2ecf20Sopenharmony_ci FC_COS_CLASS2 : FC_COS_CLASS3; 20218c2ecf20Sopenharmony_ci 20228c2ecf20Sopenharmony_ci if (pd24->prli_svc_param_word_3[0] & BIT_7) 20238c2ecf20Sopenharmony_ci fcport->flags |= FCF_CONF_COMP_SUPPORTED; 20248c2ecf20Sopenharmony_ci } else { 20258c2ecf20Sopenharmony_ci uint64_t zero = 0; 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci /* Check for logged in state. */ 20288c2ecf20Sopenharmony_ci if (pd->master_state != PD_STATE_PORT_LOGGED_IN && 20298c2ecf20Sopenharmony_ci pd->slave_state != PD_STATE_PORT_LOGGED_IN) { 20308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x100a, 20318c2ecf20Sopenharmony_ci "Unable to verify login-state (%x/%x) - " 20328c2ecf20Sopenharmony_ci "portid=%02x%02x%02x.\n", pd->master_state, 20338c2ecf20Sopenharmony_ci pd->slave_state, fcport->d_id.b.domain, 20348c2ecf20Sopenharmony_ci fcport->d_id.b.area, fcport->d_id.b.al_pa); 20358c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 20368c2ecf20Sopenharmony_ci goto gpd_error_out; 20378c2ecf20Sopenharmony_ci } 20388c2ecf20Sopenharmony_ci 20398c2ecf20Sopenharmony_ci if (fcport->loop_id == FC_NO_LOOP_ID || 20408c2ecf20Sopenharmony_ci (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 20418c2ecf20Sopenharmony_ci memcmp(fcport->port_name, pd->port_name, 8))) { 20428c2ecf20Sopenharmony_ci /* We lost the device mid way. */ 20438c2ecf20Sopenharmony_ci rval = QLA_NOT_LOGGED_IN; 20448c2ecf20Sopenharmony_ci goto gpd_error_out; 20458c2ecf20Sopenharmony_ci } 20468c2ecf20Sopenharmony_ci 20478c2ecf20Sopenharmony_ci /* Names are little-endian. */ 20488c2ecf20Sopenharmony_ci memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 20498c2ecf20Sopenharmony_ci memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 20508c2ecf20Sopenharmony_ci 20518c2ecf20Sopenharmony_ci /* Get port_id of device. */ 20528c2ecf20Sopenharmony_ci fcport->d_id.b.domain = pd->port_id[0]; 20538c2ecf20Sopenharmony_ci fcport->d_id.b.area = pd->port_id[3]; 20548c2ecf20Sopenharmony_ci fcport->d_id.b.al_pa = pd->port_id[2]; 20558c2ecf20Sopenharmony_ci fcport->d_id.b.rsvd_1 = 0; 20568c2ecf20Sopenharmony_ci 20578c2ecf20Sopenharmony_ci /* If not target must be initiator or unknown type. */ 20588c2ecf20Sopenharmony_ci if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 20598c2ecf20Sopenharmony_ci fcport->port_type = FCT_INITIATOR; 20608c2ecf20Sopenharmony_ci else 20618c2ecf20Sopenharmony_ci fcport->port_type = FCT_TARGET; 20628c2ecf20Sopenharmony_ci 20638c2ecf20Sopenharmony_ci /* Passback COS information. */ 20648c2ecf20Sopenharmony_ci fcport->supported_classes = (pd->options & BIT_4) ? 20658c2ecf20Sopenharmony_ci FC_COS_CLASS2 : FC_COS_CLASS3; 20668c2ecf20Sopenharmony_ci } 20678c2ecf20Sopenharmony_ci 20688c2ecf20Sopenharmony_cigpd_error_out: 20698c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, pd, pd_dma); 20708c2ecf20Sopenharmony_ci fcport->query = 0; 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 20738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1052, 20748c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, 20758c2ecf20Sopenharmony_ci mcp->mb[0], mcp->mb[1]); 20768c2ecf20Sopenharmony_ci } else { 20778c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053, 20788c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 20798c2ecf20Sopenharmony_ci } 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_ci return rval; 20828c2ecf20Sopenharmony_ci} 20838c2ecf20Sopenharmony_ci 20848c2ecf20Sopenharmony_ciint 20858c2ecf20Sopenharmony_ciqla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle, 20868c2ecf20Sopenharmony_ci struct port_database_24xx *pdb) 20878c2ecf20Sopenharmony_ci{ 20888c2ecf20Sopenharmony_ci mbx_cmd_t mc; 20898c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 20908c2ecf20Sopenharmony_ci dma_addr_t pdb_dma; 20918c2ecf20Sopenharmony_ci int rval; 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1115, 20948c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 20958c2ecf20Sopenharmony_ci 20968c2ecf20Sopenharmony_ci memset(pdb, 0, sizeof(*pdb)); 20978c2ecf20Sopenharmony_ci 20988c2ecf20Sopenharmony_ci pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb, 20998c2ecf20Sopenharmony_ci sizeof(*pdb), DMA_FROM_DEVICE); 21008c2ecf20Sopenharmony_ci if (!pdb_dma) { 21018c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n"); 21028c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 21038c2ecf20Sopenharmony_ci } 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_PORT_DATABASE; 21068c2ecf20Sopenharmony_ci mcp->mb[1] = nport_handle; 21078c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(pdb_dma)); 21088c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(pdb_dma)); 21098c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(pdb_dma)); 21108c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(pdb_dma)); 21118c2ecf20Sopenharmony_ci mcp->mb[9] = 0; 21128c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 21138c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 21148c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 21158c2ecf20Sopenharmony_ci mcp->buf_size = sizeof(*pdb); 21168c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_IN; 21178c2ecf20Sopenharmony_ci mcp->tov = vha->hw->login_timeout * 2; 21188c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 21198c2ecf20Sopenharmony_ci 21208c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 21218c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x111a, 21228c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 21238c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 21248c2ecf20Sopenharmony_ci } else { 21258c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111b, 21268c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 21278c2ecf20Sopenharmony_ci } 21288c2ecf20Sopenharmony_ci 21298c2ecf20Sopenharmony_ci dma_unmap_single(&vha->hw->pdev->dev, pdb_dma, 21308c2ecf20Sopenharmony_ci sizeof(*pdb), DMA_FROM_DEVICE); 21318c2ecf20Sopenharmony_ci 21328c2ecf20Sopenharmony_ci return rval; 21338c2ecf20Sopenharmony_ci} 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_ci/* 21368c2ecf20Sopenharmony_ci * qla2x00_get_firmware_state 21378c2ecf20Sopenharmony_ci * Get adapter firmware state. 21388c2ecf20Sopenharmony_ci * 21398c2ecf20Sopenharmony_ci * Input: 21408c2ecf20Sopenharmony_ci * ha = adapter block pointer. 21418c2ecf20Sopenharmony_ci * dptr = pointer for firmware state. 21428c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 21438c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 21448c2ecf20Sopenharmony_ci * 21458c2ecf20Sopenharmony_ci * Returns: 21468c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 21478c2ecf20Sopenharmony_ci * 21488c2ecf20Sopenharmony_ci * Context: 21498c2ecf20Sopenharmony_ci * Kernel context. 21508c2ecf20Sopenharmony_ci */ 21518c2ecf20Sopenharmony_ciint 21528c2ecf20Sopenharmony_ciqla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) 21538c2ecf20Sopenharmony_ci{ 21548c2ecf20Sopenharmony_ci int rval; 21558c2ecf20Sopenharmony_ci mbx_cmd_t mc; 21568c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 21578c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 21588c2ecf20Sopenharmony_ci 21598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, 21608c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 21618c2ecf20Sopenharmony_ci 21628c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 21638c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 21648c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) 21658c2ecf20Sopenharmony_ci mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 21668c2ecf20Sopenharmony_ci else 21678c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 21688c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 21698c2ecf20Sopenharmony_ci mcp->flags = 0; 21708c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 21718c2ecf20Sopenharmony_ci 21728c2ecf20Sopenharmony_ci /* Return firmware states. */ 21738c2ecf20Sopenharmony_ci states[0] = mcp->mb[1]; 21748c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) { 21758c2ecf20Sopenharmony_ci states[1] = mcp->mb[2]; 21768c2ecf20Sopenharmony_ci states[2] = mcp->mb[3]; /* SFP info */ 21778c2ecf20Sopenharmony_ci states[3] = mcp->mb[4]; 21788c2ecf20Sopenharmony_ci states[4] = mcp->mb[5]; 21798c2ecf20Sopenharmony_ci states[5] = mcp->mb[6]; /* DPORT status */ 21808c2ecf20Sopenharmony_ci } 21818c2ecf20Sopenharmony_ci 21828c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 21838c2ecf20Sopenharmony_ci /*EMPTY*/ 21848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); 21858c2ecf20Sopenharmony_ci } else { 21868c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 21878c2ecf20Sopenharmony_ci if (mcp->mb[2] == 6 || mcp->mb[3] == 2) 21888c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119e, 21898c2ecf20Sopenharmony_ci "Invalid SFP/Validation Failed\n"); 21908c2ecf20Sopenharmony_ci } 21918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056, 21928c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 21938c2ecf20Sopenharmony_ci } 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci return rval; 21968c2ecf20Sopenharmony_ci} 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_ci/* 21998c2ecf20Sopenharmony_ci * qla2x00_get_port_name 22008c2ecf20Sopenharmony_ci * Issue get port name mailbox command. 22018c2ecf20Sopenharmony_ci * Returned name is in big endian format. 22028c2ecf20Sopenharmony_ci * 22038c2ecf20Sopenharmony_ci * Input: 22048c2ecf20Sopenharmony_ci * ha = adapter block pointer. 22058c2ecf20Sopenharmony_ci * loop_id = loop ID of device. 22068c2ecf20Sopenharmony_ci * name = pointer for name. 22078c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 22088c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 22098c2ecf20Sopenharmony_ci * 22108c2ecf20Sopenharmony_ci * Returns: 22118c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 22128c2ecf20Sopenharmony_ci * 22138c2ecf20Sopenharmony_ci * Context: 22148c2ecf20Sopenharmony_ci * Kernel context. 22158c2ecf20Sopenharmony_ci */ 22168c2ecf20Sopenharmony_ciint 22178c2ecf20Sopenharmony_ciqla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name, 22188c2ecf20Sopenharmony_ci uint8_t opt) 22198c2ecf20Sopenharmony_ci{ 22208c2ecf20Sopenharmony_ci int rval; 22218c2ecf20Sopenharmony_ci mbx_cmd_t mc; 22228c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 22238c2ecf20Sopenharmony_ci 22248c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057, 22258c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 22268c2ecf20Sopenharmony_ci 22278c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_PORT_NAME; 22288c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 22298c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_1|MBX_0; 22308c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(vha->hw)) { 22318c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 22328c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 22338c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 22348c2ecf20Sopenharmony_ci } else { 22358c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id << 8 | opt; 22368c2ecf20Sopenharmony_ci } 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 22398c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 22408c2ecf20Sopenharmony_ci mcp->flags = 0; 22418c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 22428c2ecf20Sopenharmony_ci 22438c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 22448c2ecf20Sopenharmony_ci /*EMPTY*/ 22458c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval); 22468c2ecf20Sopenharmony_ci } else { 22478c2ecf20Sopenharmony_ci if (name != NULL) { 22488c2ecf20Sopenharmony_ci /* This function returns name in big endian. */ 22498c2ecf20Sopenharmony_ci name[0] = MSB(mcp->mb[2]); 22508c2ecf20Sopenharmony_ci name[1] = LSB(mcp->mb[2]); 22518c2ecf20Sopenharmony_ci name[2] = MSB(mcp->mb[3]); 22528c2ecf20Sopenharmony_ci name[3] = LSB(mcp->mb[3]); 22538c2ecf20Sopenharmony_ci name[4] = MSB(mcp->mb[6]); 22548c2ecf20Sopenharmony_ci name[5] = LSB(mcp->mb[6]); 22558c2ecf20Sopenharmony_ci name[6] = MSB(mcp->mb[7]); 22568c2ecf20Sopenharmony_ci name[7] = LSB(mcp->mb[7]); 22578c2ecf20Sopenharmony_ci } 22588c2ecf20Sopenharmony_ci 22598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059, 22608c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 22618c2ecf20Sopenharmony_ci } 22628c2ecf20Sopenharmony_ci 22638c2ecf20Sopenharmony_ci return rval; 22648c2ecf20Sopenharmony_ci} 22658c2ecf20Sopenharmony_ci 22668c2ecf20Sopenharmony_ci/* 22678c2ecf20Sopenharmony_ci * qla24xx_link_initialization 22688c2ecf20Sopenharmony_ci * Issue link initialization mailbox command. 22698c2ecf20Sopenharmony_ci * 22708c2ecf20Sopenharmony_ci * Input: 22718c2ecf20Sopenharmony_ci * ha = adapter block pointer. 22728c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 22738c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 22748c2ecf20Sopenharmony_ci * 22758c2ecf20Sopenharmony_ci * Returns: 22768c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 22778c2ecf20Sopenharmony_ci * 22788c2ecf20Sopenharmony_ci * Context: 22798c2ecf20Sopenharmony_ci * Kernel context. 22808c2ecf20Sopenharmony_ci */ 22818c2ecf20Sopenharmony_ciint 22828c2ecf20Sopenharmony_ciqla24xx_link_initialize(scsi_qla_host_t *vha) 22838c2ecf20Sopenharmony_ci{ 22848c2ecf20Sopenharmony_ci int rval; 22858c2ecf20Sopenharmony_ci mbx_cmd_t mc; 22868c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 22878c2ecf20Sopenharmony_ci 22888c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152, 22898c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 22908c2ecf20Sopenharmony_ci 22918c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw)) 22928c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 22938c2ecf20Sopenharmony_ci 22948c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LINK_INITIALIZATION; 22958c2ecf20Sopenharmony_ci mcp->mb[1] = BIT_4; 22968c2ecf20Sopenharmony_ci if (vha->hw->operating_mode == LOOP) 22978c2ecf20Sopenharmony_ci mcp->mb[1] |= BIT_6; 22988c2ecf20Sopenharmony_ci else 22998c2ecf20Sopenharmony_ci mcp->mb[1] |= BIT_5; 23008c2ecf20Sopenharmony_ci mcp->mb[2] = 0; 23018c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 23028c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 23038c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 23048c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 23058c2ecf20Sopenharmony_ci mcp->flags = 0; 23068c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 23078c2ecf20Sopenharmony_ci 23088c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 23098c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval); 23108c2ecf20Sopenharmony_ci } else { 23118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154, 23128c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 23138c2ecf20Sopenharmony_ci } 23148c2ecf20Sopenharmony_ci 23158c2ecf20Sopenharmony_ci return rval; 23168c2ecf20Sopenharmony_ci} 23178c2ecf20Sopenharmony_ci 23188c2ecf20Sopenharmony_ci/* 23198c2ecf20Sopenharmony_ci * qla2x00_lip_reset 23208c2ecf20Sopenharmony_ci * Issue LIP reset mailbox command. 23218c2ecf20Sopenharmony_ci * 23228c2ecf20Sopenharmony_ci * Input: 23238c2ecf20Sopenharmony_ci * ha = adapter block pointer. 23248c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 23258c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 23268c2ecf20Sopenharmony_ci * 23278c2ecf20Sopenharmony_ci * Returns: 23288c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 23298c2ecf20Sopenharmony_ci * 23308c2ecf20Sopenharmony_ci * Context: 23318c2ecf20Sopenharmony_ci * Kernel context. 23328c2ecf20Sopenharmony_ci */ 23338c2ecf20Sopenharmony_ciint 23348c2ecf20Sopenharmony_ciqla2x00_lip_reset(scsi_qla_host_t *vha) 23358c2ecf20Sopenharmony_ci{ 23368c2ecf20Sopenharmony_ci int rval; 23378c2ecf20Sopenharmony_ci mbx_cmd_t mc; 23388c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 23398c2ecf20Sopenharmony_ci 23408c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_disc, vha, 0x105a, 23418c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 23428c2ecf20Sopenharmony_ci 23438c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(vha->hw)) { 23448c2ecf20Sopenharmony_ci /* Logout across all FCFs. */ 23458c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LIP_FULL_LOGIN; 23468c2ecf20Sopenharmony_ci mcp->mb[1] = BIT_1; 23478c2ecf20Sopenharmony_ci mcp->mb[2] = 0; 23488c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 23498c2ecf20Sopenharmony_ci } else if (IS_FWI2_CAPABLE(vha->hw)) { 23508c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LIP_FULL_LOGIN; 23518c2ecf20Sopenharmony_ci mcp->mb[1] = BIT_4; 23528c2ecf20Sopenharmony_ci mcp->mb[2] = 0; 23538c2ecf20Sopenharmony_ci mcp->mb[3] = vha->hw->loop_reset_delay; 23548c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 23558c2ecf20Sopenharmony_ci } else { 23568c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LIP_RESET; 23578c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 23588c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(vha->hw)) { 23598c2ecf20Sopenharmony_ci mcp->mb[1] = 0x00ff; 23608c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 23618c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 23628c2ecf20Sopenharmony_ci } else { 23638c2ecf20Sopenharmony_ci mcp->mb[1] = 0xff00; 23648c2ecf20Sopenharmony_ci } 23658c2ecf20Sopenharmony_ci mcp->mb[2] = vha->hw->loop_reset_delay; 23668c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 23678c2ecf20Sopenharmony_ci } 23688c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 23698c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 23708c2ecf20Sopenharmony_ci mcp->flags = 0; 23718c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 23728c2ecf20Sopenharmony_ci 23738c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 23748c2ecf20Sopenharmony_ci /*EMPTY*/ 23758c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval); 23768c2ecf20Sopenharmony_ci } else { 23778c2ecf20Sopenharmony_ci /*EMPTY*/ 23788c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c, 23798c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 23808c2ecf20Sopenharmony_ci } 23818c2ecf20Sopenharmony_ci 23828c2ecf20Sopenharmony_ci return rval; 23838c2ecf20Sopenharmony_ci} 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_ci/* 23868c2ecf20Sopenharmony_ci * qla2x00_send_sns 23878c2ecf20Sopenharmony_ci * Send SNS command. 23888c2ecf20Sopenharmony_ci * 23898c2ecf20Sopenharmony_ci * Input: 23908c2ecf20Sopenharmony_ci * ha = adapter block pointer. 23918c2ecf20Sopenharmony_ci * sns = pointer for command. 23928c2ecf20Sopenharmony_ci * cmd_size = command size. 23938c2ecf20Sopenharmony_ci * buf_size = response/command size. 23948c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 23958c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 23968c2ecf20Sopenharmony_ci * 23978c2ecf20Sopenharmony_ci * Returns: 23988c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 23998c2ecf20Sopenharmony_ci * 24008c2ecf20Sopenharmony_ci * Context: 24018c2ecf20Sopenharmony_ci * Kernel context. 24028c2ecf20Sopenharmony_ci */ 24038c2ecf20Sopenharmony_ciint 24048c2ecf20Sopenharmony_ciqla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address, 24058c2ecf20Sopenharmony_ci uint16_t cmd_size, size_t buf_size) 24068c2ecf20Sopenharmony_ci{ 24078c2ecf20Sopenharmony_ci int rval; 24088c2ecf20Sopenharmony_ci mbx_cmd_t mc; 24098c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d, 24128c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 24138c2ecf20Sopenharmony_ci 24148c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e, 24158c2ecf20Sopenharmony_ci "Retry cnt=%d ratov=%d total tov=%d.\n", 24168c2ecf20Sopenharmony_ci vha->hw->retry_count, vha->hw->login_timeout, mcp->tov); 24178c2ecf20Sopenharmony_ci 24188c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SEND_SNS_COMMAND; 24198c2ecf20Sopenharmony_ci mcp->mb[1] = cmd_size; 24208c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(sns_phys_address); 24218c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(sns_phys_address); 24228c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(sns_phys_address)); 24238c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(sns_phys_address)); 24248c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 24258c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0|MBX_1; 24268c2ecf20Sopenharmony_ci mcp->buf_size = buf_size; 24278c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN; 24288c2ecf20Sopenharmony_ci mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2); 24298c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 24308c2ecf20Sopenharmony_ci 24318c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 24328c2ecf20Sopenharmony_ci /*EMPTY*/ 24338c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x105f, 24348c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 24358c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 24368c2ecf20Sopenharmony_ci } else { 24378c2ecf20Sopenharmony_ci /*EMPTY*/ 24388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060, 24398c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 24408c2ecf20Sopenharmony_ci } 24418c2ecf20Sopenharmony_ci 24428c2ecf20Sopenharmony_ci return rval; 24438c2ecf20Sopenharmony_ci} 24448c2ecf20Sopenharmony_ci 24458c2ecf20Sopenharmony_ciint 24468c2ecf20Sopenharmony_ciqla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 24478c2ecf20Sopenharmony_ci uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 24488c2ecf20Sopenharmony_ci{ 24498c2ecf20Sopenharmony_ci int rval; 24508c2ecf20Sopenharmony_ci 24518c2ecf20Sopenharmony_ci struct logio_entry_24xx *lg; 24528c2ecf20Sopenharmony_ci dma_addr_t lg_dma; 24538c2ecf20Sopenharmony_ci uint32_t iop[2]; 24548c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 24558c2ecf20Sopenharmony_ci struct req_que *req; 24568c2ecf20Sopenharmony_ci 24578c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061, 24588c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 24598c2ecf20Sopenharmony_ci 24608c2ecf20Sopenharmony_ci if (vha->vp_idx && vha->qpair) 24618c2ecf20Sopenharmony_ci req = vha->qpair->req; 24628c2ecf20Sopenharmony_ci else 24638c2ecf20Sopenharmony_ci req = ha->req_q_map[0]; 24648c2ecf20Sopenharmony_ci 24658c2ecf20Sopenharmony_ci lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 24668c2ecf20Sopenharmony_ci if (lg == NULL) { 24678c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1062, 24688c2ecf20Sopenharmony_ci "Failed to allocate login IOCB.\n"); 24698c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 24708c2ecf20Sopenharmony_ci } 24718c2ecf20Sopenharmony_ci 24728c2ecf20Sopenharmony_ci lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 24738c2ecf20Sopenharmony_ci lg->entry_count = 1; 24748c2ecf20Sopenharmony_ci lg->handle = make_handle(req->id, lg->handle); 24758c2ecf20Sopenharmony_ci lg->nport_handle = cpu_to_le16(loop_id); 24768c2ecf20Sopenharmony_ci lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI); 24778c2ecf20Sopenharmony_ci if (opt & BIT_0) 24788c2ecf20Sopenharmony_ci lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI); 24798c2ecf20Sopenharmony_ci if (opt & BIT_1) 24808c2ecf20Sopenharmony_ci lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI); 24818c2ecf20Sopenharmony_ci lg->port_id[0] = al_pa; 24828c2ecf20Sopenharmony_ci lg->port_id[1] = area; 24838c2ecf20Sopenharmony_ci lg->port_id[2] = domain; 24848c2ecf20Sopenharmony_ci lg->vp_index = vha->vp_idx; 24858c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0, 24868c2ecf20Sopenharmony_ci (ha->r_a_tov / 10 * 2) + 2); 24878c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 24888c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1063, 24898c2ecf20Sopenharmony_ci "Failed to issue login IOCB (%x).\n", rval); 24908c2ecf20Sopenharmony_ci } else if (lg->entry_status != 0) { 24918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1064, 24928c2ecf20Sopenharmony_ci "Failed to complete IOCB -- error status (%x).\n", 24938c2ecf20Sopenharmony_ci lg->entry_status); 24948c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 24958c2ecf20Sopenharmony_ci } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) { 24968c2ecf20Sopenharmony_ci iop[0] = le32_to_cpu(lg->io_parameter[0]); 24978c2ecf20Sopenharmony_ci iop[1] = le32_to_cpu(lg->io_parameter[1]); 24988c2ecf20Sopenharmony_ci 24998c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1065, 25008c2ecf20Sopenharmony_ci "Failed to complete IOCB -- completion status (%x) " 25018c2ecf20Sopenharmony_ci "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status), 25028c2ecf20Sopenharmony_ci iop[0], iop[1]); 25038c2ecf20Sopenharmony_ci 25048c2ecf20Sopenharmony_ci switch (iop[0]) { 25058c2ecf20Sopenharmony_ci case LSC_SCODE_PORTID_USED: 25068c2ecf20Sopenharmony_ci mb[0] = MBS_PORT_ID_USED; 25078c2ecf20Sopenharmony_ci mb[1] = LSW(iop[1]); 25088c2ecf20Sopenharmony_ci break; 25098c2ecf20Sopenharmony_ci case LSC_SCODE_NPORT_USED: 25108c2ecf20Sopenharmony_ci mb[0] = MBS_LOOP_ID_USED; 25118c2ecf20Sopenharmony_ci break; 25128c2ecf20Sopenharmony_ci case LSC_SCODE_NOLINK: 25138c2ecf20Sopenharmony_ci case LSC_SCODE_NOIOCB: 25148c2ecf20Sopenharmony_ci case LSC_SCODE_NOXCB: 25158c2ecf20Sopenharmony_ci case LSC_SCODE_CMD_FAILED: 25168c2ecf20Sopenharmony_ci case LSC_SCODE_NOFABRIC: 25178c2ecf20Sopenharmony_ci case LSC_SCODE_FW_NOT_READY: 25188c2ecf20Sopenharmony_ci case LSC_SCODE_NOT_LOGGED_IN: 25198c2ecf20Sopenharmony_ci case LSC_SCODE_NOPCB: 25208c2ecf20Sopenharmony_ci case LSC_SCODE_ELS_REJECT: 25218c2ecf20Sopenharmony_ci case LSC_SCODE_CMD_PARAM_ERR: 25228c2ecf20Sopenharmony_ci case LSC_SCODE_NONPORT: 25238c2ecf20Sopenharmony_ci case LSC_SCODE_LOGGED_IN: 25248c2ecf20Sopenharmony_ci case LSC_SCODE_NOFLOGI_ACC: 25258c2ecf20Sopenharmony_ci default: 25268c2ecf20Sopenharmony_ci mb[0] = MBS_COMMAND_ERROR; 25278c2ecf20Sopenharmony_ci break; 25288c2ecf20Sopenharmony_ci } 25298c2ecf20Sopenharmony_ci } else { 25308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066, 25318c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 25328c2ecf20Sopenharmony_ci 25338c2ecf20Sopenharmony_ci iop[0] = le32_to_cpu(lg->io_parameter[0]); 25348c2ecf20Sopenharmony_ci 25358c2ecf20Sopenharmony_ci mb[0] = MBS_COMMAND_COMPLETE; 25368c2ecf20Sopenharmony_ci mb[1] = 0; 25378c2ecf20Sopenharmony_ci if (iop[0] & BIT_4) { 25388c2ecf20Sopenharmony_ci if (iop[0] & BIT_8) 25398c2ecf20Sopenharmony_ci mb[1] |= BIT_1; 25408c2ecf20Sopenharmony_ci } else 25418c2ecf20Sopenharmony_ci mb[1] = BIT_0; 25428c2ecf20Sopenharmony_ci 25438c2ecf20Sopenharmony_ci /* Passback COS information. */ 25448c2ecf20Sopenharmony_ci mb[10] = 0; 25458c2ecf20Sopenharmony_ci if (lg->io_parameter[7] || lg->io_parameter[8]) 25468c2ecf20Sopenharmony_ci mb[10] |= BIT_0; /* Class 2. */ 25478c2ecf20Sopenharmony_ci if (lg->io_parameter[9] || lg->io_parameter[10]) 25488c2ecf20Sopenharmony_ci mb[10] |= BIT_1; /* Class 3. */ 25498c2ecf20Sopenharmony_ci if (lg->io_parameter[0] & cpu_to_le32(BIT_7)) 25508c2ecf20Sopenharmony_ci mb[10] |= BIT_7; /* Confirmed Completion 25518c2ecf20Sopenharmony_ci * Allowed 25528c2ecf20Sopenharmony_ci */ 25538c2ecf20Sopenharmony_ci } 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, lg, lg_dma); 25568c2ecf20Sopenharmony_ci 25578c2ecf20Sopenharmony_ci return rval; 25588c2ecf20Sopenharmony_ci} 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_ci/* 25618c2ecf20Sopenharmony_ci * qla2x00_login_fabric 25628c2ecf20Sopenharmony_ci * Issue login fabric port mailbox command. 25638c2ecf20Sopenharmony_ci * 25648c2ecf20Sopenharmony_ci * Input: 25658c2ecf20Sopenharmony_ci * ha = adapter block pointer. 25668c2ecf20Sopenharmony_ci * loop_id = device loop ID. 25678c2ecf20Sopenharmony_ci * domain = device domain. 25688c2ecf20Sopenharmony_ci * area = device area. 25698c2ecf20Sopenharmony_ci * al_pa = device AL_PA. 25708c2ecf20Sopenharmony_ci * status = pointer for return status. 25718c2ecf20Sopenharmony_ci * opt = command options. 25728c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 25738c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 25748c2ecf20Sopenharmony_ci * 25758c2ecf20Sopenharmony_ci * Returns: 25768c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 25778c2ecf20Sopenharmony_ci * 25788c2ecf20Sopenharmony_ci * Context: 25798c2ecf20Sopenharmony_ci * Kernel context. 25808c2ecf20Sopenharmony_ci */ 25818c2ecf20Sopenharmony_ciint 25828c2ecf20Sopenharmony_ciqla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 25838c2ecf20Sopenharmony_ci uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 25848c2ecf20Sopenharmony_ci{ 25858c2ecf20Sopenharmony_ci int rval; 25868c2ecf20Sopenharmony_ci mbx_cmd_t mc; 25878c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 25888c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 25898c2ecf20Sopenharmony_ci 25908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067, 25918c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 25928c2ecf20Sopenharmony_ci 25938c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 25948c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 25958c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(ha)) { 25968c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 25978c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 25988c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 25998c2ecf20Sopenharmony_ci } else { 26008c2ecf20Sopenharmony_ci mcp->mb[1] = (loop_id << 8) | opt; 26018c2ecf20Sopenharmony_ci } 26028c2ecf20Sopenharmony_ci mcp->mb[2] = domain; 26038c2ecf20Sopenharmony_ci mcp->mb[3] = area << 8 | al_pa; 26048c2ecf20Sopenharmony_ci 26058c2ecf20Sopenharmony_ci mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 26068c2ecf20Sopenharmony_ci mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 26078c2ecf20Sopenharmony_ci mcp->flags = 0; 26088c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 26098c2ecf20Sopenharmony_ci 26108c2ecf20Sopenharmony_ci /* Return mailbox statuses. */ 26118c2ecf20Sopenharmony_ci if (mb != NULL) { 26128c2ecf20Sopenharmony_ci mb[0] = mcp->mb[0]; 26138c2ecf20Sopenharmony_ci mb[1] = mcp->mb[1]; 26148c2ecf20Sopenharmony_ci mb[2] = mcp->mb[2]; 26158c2ecf20Sopenharmony_ci mb[6] = mcp->mb[6]; 26168c2ecf20Sopenharmony_ci mb[7] = mcp->mb[7]; 26178c2ecf20Sopenharmony_ci /* COS retrieved from Get-Port-Database mailbox command. */ 26188c2ecf20Sopenharmony_ci mb[10] = 0; 26198c2ecf20Sopenharmony_ci } 26208c2ecf20Sopenharmony_ci 26218c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 26228c2ecf20Sopenharmony_ci /* RLU tmp code: need to change main mailbox_command function to 26238c2ecf20Sopenharmony_ci * return ok even when the mailbox completion value is not 26248c2ecf20Sopenharmony_ci * SUCCESS. The caller needs to be responsible to interpret 26258c2ecf20Sopenharmony_ci * the return values of this mailbox command if we're not 26268c2ecf20Sopenharmony_ci * to change too much of the existing code. 26278c2ecf20Sopenharmony_ci */ 26288c2ecf20Sopenharmony_ci if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 || 26298c2ecf20Sopenharmony_ci mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 || 26308c2ecf20Sopenharmony_ci mcp->mb[0] == 0x4006) 26318c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 26328c2ecf20Sopenharmony_ci 26338c2ecf20Sopenharmony_ci /*EMPTY*/ 26348c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1068, 26358c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 26368c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 26378c2ecf20Sopenharmony_ci } else { 26388c2ecf20Sopenharmony_ci /*EMPTY*/ 26398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069, 26408c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 26418c2ecf20Sopenharmony_ci } 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_ci return rval; 26448c2ecf20Sopenharmony_ci} 26458c2ecf20Sopenharmony_ci 26468c2ecf20Sopenharmony_ci/* 26478c2ecf20Sopenharmony_ci * qla2x00_login_local_device 26488c2ecf20Sopenharmony_ci * Issue login loop port mailbox command. 26498c2ecf20Sopenharmony_ci * 26508c2ecf20Sopenharmony_ci * Input: 26518c2ecf20Sopenharmony_ci * ha = adapter block pointer. 26528c2ecf20Sopenharmony_ci * loop_id = device loop ID. 26538c2ecf20Sopenharmony_ci * opt = command options. 26548c2ecf20Sopenharmony_ci * 26558c2ecf20Sopenharmony_ci * Returns: 26568c2ecf20Sopenharmony_ci * Return status code. 26578c2ecf20Sopenharmony_ci * 26588c2ecf20Sopenharmony_ci * Context: 26598c2ecf20Sopenharmony_ci * Kernel context. 26608c2ecf20Sopenharmony_ci * 26618c2ecf20Sopenharmony_ci */ 26628c2ecf20Sopenharmony_ciint 26638c2ecf20Sopenharmony_ciqla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport, 26648c2ecf20Sopenharmony_ci uint16_t *mb_ret, uint8_t opt) 26658c2ecf20Sopenharmony_ci{ 26668c2ecf20Sopenharmony_ci int rval; 26678c2ecf20Sopenharmony_ci mbx_cmd_t mc; 26688c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 26698c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 26708c2ecf20Sopenharmony_ci 26718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a, 26728c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 26738c2ecf20Sopenharmony_ci 26748c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) 26758c2ecf20Sopenharmony_ci return qla24xx_login_fabric(vha, fcport->loop_id, 26768c2ecf20Sopenharmony_ci fcport->d_id.b.domain, fcport->d_id.b.area, 26778c2ecf20Sopenharmony_ci fcport->d_id.b.al_pa, mb_ret, opt); 26788c2ecf20Sopenharmony_ci 26798c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 26808c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(ha)) 26818c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 26828c2ecf20Sopenharmony_ci else 26838c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id << 8; 26848c2ecf20Sopenharmony_ci mcp->mb[2] = opt; 26858c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 26868c2ecf20Sopenharmony_ci mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0; 26878c2ecf20Sopenharmony_ci mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 26888c2ecf20Sopenharmony_ci mcp->flags = 0; 26898c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 26908c2ecf20Sopenharmony_ci 26918c2ecf20Sopenharmony_ci /* Return mailbox statuses. */ 26928c2ecf20Sopenharmony_ci if (mb_ret != NULL) { 26938c2ecf20Sopenharmony_ci mb_ret[0] = mcp->mb[0]; 26948c2ecf20Sopenharmony_ci mb_ret[1] = mcp->mb[1]; 26958c2ecf20Sopenharmony_ci mb_ret[6] = mcp->mb[6]; 26968c2ecf20Sopenharmony_ci mb_ret[7] = mcp->mb[7]; 26978c2ecf20Sopenharmony_ci } 26988c2ecf20Sopenharmony_ci 26998c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 27008c2ecf20Sopenharmony_ci /* AV tmp code: need to change main mailbox_command function to 27018c2ecf20Sopenharmony_ci * return ok even when the mailbox completion value is not 27028c2ecf20Sopenharmony_ci * SUCCESS. The caller needs to be responsible to interpret 27038c2ecf20Sopenharmony_ci * the return values of this mailbox command if we're not 27048c2ecf20Sopenharmony_ci * to change too much of the existing code. 27058c2ecf20Sopenharmony_ci */ 27068c2ecf20Sopenharmony_ci if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006) 27078c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 27088c2ecf20Sopenharmony_ci 27098c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x106b, 27108c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n", 27118c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]); 27128c2ecf20Sopenharmony_ci } else { 27138c2ecf20Sopenharmony_ci /*EMPTY*/ 27148c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c, 27158c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 27168c2ecf20Sopenharmony_ci } 27178c2ecf20Sopenharmony_ci 27188c2ecf20Sopenharmony_ci return (rval); 27198c2ecf20Sopenharmony_ci} 27208c2ecf20Sopenharmony_ci 27218c2ecf20Sopenharmony_ciint 27228c2ecf20Sopenharmony_ciqla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 27238c2ecf20Sopenharmony_ci uint8_t area, uint8_t al_pa) 27248c2ecf20Sopenharmony_ci{ 27258c2ecf20Sopenharmony_ci int rval; 27268c2ecf20Sopenharmony_ci struct logio_entry_24xx *lg; 27278c2ecf20Sopenharmony_ci dma_addr_t lg_dma; 27288c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 27298c2ecf20Sopenharmony_ci struct req_que *req; 27308c2ecf20Sopenharmony_ci 27318c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d, 27328c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 27338c2ecf20Sopenharmony_ci 27348c2ecf20Sopenharmony_ci lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 27358c2ecf20Sopenharmony_ci if (lg == NULL) { 27368c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x106e, 27378c2ecf20Sopenharmony_ci "Failed to allocate logout IOCB.\n"); 27388c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 27398c2ecf20Sopenharmony_ci } 27408c2ecf20Sopenharmony_ci 27418c2ecf20Sopenharmony_ci req = vha->req; 27428c2ecf20Sopenharmony_ci lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 27438c2ecf20Sopenharmony_ci lg->entry_count = 1; 27448c2ecf20Sopenharmony_ci lg->handle = make_handle(req->id, lg->handle); 27458c2ecf20Sopenharmony_ci lg->nport_handle = cpu_to_le16(loop_id); 27468c2ecf20Sopenharmony_ci lg->control_flags = 27478c2ecf20Sopenharmony_ci cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO| 27488c2ecf20Sopenharmony_ci LCF_FREE_NPORT); 27498c2ecf20Sopenharmony_ci lg->port_id[0] = al_pa; 27508c2ecf20Sopenharmony_ci lg->port_id[1] = area; 27518c2ecf20Sopenharmony_ci lg->port_id[2] = domain; 27528c2ecf20Sopenharmony_ci lg->vp_index = vha->vp_idx; 27538c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0, 27548c2ecf20Sopenharmony_ci (ha->r_a_tov / 10 * 2) + 2); 27558c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 27568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x106f, 27578c2ecf20Sopenharmony_ci "Failed to issue logout IOCB (%x).\n", rval); 27588c2ecf20Sopenharmony_ci } else if (lg->entry_status != 0) { 27598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1070, 27608c2ecf20Sopenharmony_ci "Failed to complete IOCB -- error status (%x).\n", 27618c2ecf20Sopenharmony_ci lg->entry_status); 27628c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 27638c2ecf20Sopenharmony_ci } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) { 27648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1071, 27658c2ecf20Sopenharmony_ci "Failed to complete IOCB -- completion status (%x) " 27668c2ecf20Sopenharmony_ci "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status), 27678c2ecf20Sopenharmony_ci le32_to_cpu(lg->io_parameter[0]), 27688c2ecf20Sopenharmony_ci le32_to_cpu(lg->io_parameter[1])); 27698c2ecf20Sopenharmony_ci } else { 27708c2ecf20Sopenharmony_ci /*EMPTY*/ 27718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072, 27728c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 27738c2ecf20Sopenharmony_ci } 27748c2ecf20Sopenharmony_ci 27758c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, lg, lg_dma); 27768c2ecf20Sopenharmony_ci 27778c2ecf20Sopenharmony_ci return rval; 27788c2ecf20Sopenharmony_ci} 27798c2ecf20Sopenharmony_ci 27808c2ecf20Sopenharmony_ci/* 27818c2ecf20Sopenharmony_ci * qla2x00_fabric_logout 27828c2ecf20Sopenharmony_ci * Issue logout fabric port mailbox command. 27838c2ecf20Sopenharmony_ci * 27848c2ecf20Sopenharmony_ci * Input: 27858c2ecf20Sopenharmony_ci * ha = adapter block pointer. 27868c2ecf20Sopenharmony_ci * loop_id = device loop ID. 27878c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 27888c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 27898c2ecf20Sopenharmony_ci * 27908c2ecf20Sopenharmony_ci * Returns: 27918c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 27928c2ecf20Sopenharmony_ci * 27938c2ecf20Sopenharmony_ci * Context: 27948c2ecf20Sopenharmony_ci * Kernel context. 27958c2ecf20Sopenharmony_ci */ 27968c2ecf20Sopenharmony_ciint 27978c2ecf20Sopenharmony_ciqla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 27988c2ecf20Sopenharmony_ci uint8_t area, uint8_t al_pa) 27998c2ecf20Sopenharmony_ci{ 28008c2ecf20Sopenharmony_ci int rval; 28018c2ecf20Sopenharmony_ci mbx_cmd_t mc; 28028c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 28038c2ecf20Sopenharmony_ci 28048c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073, 28058c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 28068c2ecf20Sopenharmony_ci 28078c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 28088c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 28098c2ecf20Sopenharmony_ci if (HAS_EXTENDED_IDS(vha->hw)) { 28108c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 28118c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 28128c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10; 28138c2ecf20Sopenharmony_ci } else { 28148c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id << 8; 28158c2ecf20Sopenharmony_ci } 28168c2ecf20Sopenharmony_ci 28178c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 28188c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 28198c2ecf20Sopenharmony_ci mcp->flags = 0; 28208c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 28218c2ecf20Sopenharmony_ci 28228c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 28238c2ecf20Sopenharmony_ci /*EMPTY*/ 28248c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1074, 28258c2ecf20Sopenharmony_ci "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]); 28268c2ecf20Sopenharmony_ci } else { 28278c2ecf20Sopenharmony_ci /*EMPTY*/ 28288c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075, 28298c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 28308c2ecf20Sopenharmony_ci } 28318c2ecf20Sopenharmony_ci 28328c2ecf20Sopenharmony_ci return rval; 28338c2ecf20Sopenharmony_ci} 28348c2ecf20Sopenharmony_ci 28358c2ecf20Sopenharmony_ci/* 28368c2ecf20Sopenharmony_ci * qla2x00_full_login_lip 28378c2ecf20Sopenharmony_ci * Issue full login LIP mailbox command. 28388c2ecf20Sopenharmony_ci * 28398c2ecf20Sopenharmony_ci * Input: 28408c2ecf20Sopenharmony_ci * ha = adapter block pointer. 28418c2ecf20Sopenharmony_ci * TARGET_QUEUE_LOCK must be released. 28428c2ecf20Sopenharmony_ci * ADAPTER_STATE_LOCK must be released. 28438c2ecf20Sopenharmony_ci * 28448c2ecf20Sopenharmony_ci * Returns: 28458c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 28468c2ecf20Sopenharmony_ci * 28478c2ecf20Sopenharmony_ci * Context: 28488c2ecf20Sopenharmony_ci * Kernel context. 28498c2ecf20Sopenharmony_ci */ 28508c2ecf20Sopenharmony_ciint 28518c2ecf20Sopenharmony_ciqla2x00_full_login_lip(scsi_qla_host_t *vha) 28528c2ecf20Sopenharmony_ci{ 28538c2ecf20Sopenharmony_ci int rval; 28548c2ecf20Sopenharmony_ci mbx_cmd_t mc; 28558c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 28568c2ecf20Sopenharmony_ci 28578c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076, 28588c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 28598c2ecf20Sopenharmony_ci 28608c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_LIP_FULL_LOGIN; 28618c2ecf20Sopenharmony_ci mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_4 : 0; 28628c2ecf20Sopenharmony_ci mcp->mb[2] = 0; 28638c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 28648c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 28658c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 28668c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 28678c2ecf20Sopenharmony_ci mcp->flags = 0; 28688c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 28698c2ecf20Sopenharmony_ci 28708c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 28718c2ecf20Sopenharmony_ci /*EMPTY*/ 28728c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval); 28738c2ecf20Sopenharmony_ci } else { 28748c2ecf20Sopenharmony_ci /*EMPTY*/ 28758c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078, 28768c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 28778c2ecf20Sopenharmony_ci } 28788c2ecf20Sopenharmony_ci 28798c2ecf20Sopenharmony_ci return rval; 28808c2ecf20Sopenharmony_ci} 28818c2ecf20Sopenharmony_ci 28828c2ecf20Sopenharmony_ci/* 28838c2ecf20Sopenharmony_ci * qla2x00_get_id_list 28848c2ecf20Sopenharmony_ci * 28858c2ecf20Sopenharmony_ci * Input: 28868c2ecf20Sopenharmony_ci * ha = adapter block pointer. 28878c2ecf20Sopenharmony_ci * 28888c2ecf20Sopenharmony_ci * Returns: 28898c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 28908c2ecf20Sopenharmony_ci * 28918c2ecf20Sopenharmony_ci * Context: 28928c2ecf20Sopenharmony_ci * Kernel context. 28938c2ecf20Sopenharmony_ci */ 28948c2ecf20Sopenharmony_ciint 28958c2ecf20Sopenharmony_ciqla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma, 28968c2ecf20Sopenharmony_ci uint16_t *entries) 28978c2ecf20Sopenharmony_ci{ 28988c2ecf20Sopenharmony_ci int rval; 28998c2ecf20Sopenharmony_ci mbx_cmd_t mc; 29008c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 29018c2ecf20Sopenharmony_ci 29028c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079, 29038c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 29048c2ecf20Sopenharmony_ci 29058c2ecf20Sopenharmony_ci if (id_list == NULL) 29068c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 29078c2ecf20Sopenharmony_ci 29088c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_ID_LIST; 29098c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 29108c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) { 29118c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(id_list_dma); 29128c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(id_list_dma); 29138c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(id_list_dma)); 29148c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(id_list_dma)); 29158c2ecf20Sopenharmony_ci mcp->mb[8] = 0; 29168c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 29178c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2; 29188c2ecf20Sopenharmony_ci } else { 29198c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(id_list_dma); 29208c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(id_list_dma); 29218c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(MSD(id_list_dma)); 29228c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(MSD(id_list_dma)); 29238c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; 29248c2ecf20Sopenharmony_ci } 29258c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 29268c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 29278c2ecf20Sopenharmony_ci mcp->flags = 0; 29288c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 29298c2ecf20Sopenharmony_ci 29308c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 29318c2ecf20Sopenharmony_ci /*EMPTY*/ 29328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval); 29338c2ecf20Sopenharmony_ci } else { 29348c2ecf20Sopenharmony_ci *entries = mcp->mb[1]; 29358c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b, 29368c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 29378c2ecf20Sopenharmony_ci } 29388c2ecf20Sopenharmony_ci 29398c2ecf20Sopenharmony_ci return rval; 29408c2ecf20Sopenharmony_ci} 29418c2ecf20Sopenharmony_ci 29428c2ecf20Sopenharmony_ci/* 29438c2ecf20Sopenharmony_ci * qla2x00_get_resource_cnts 29448c2ecf20Sopenharmony_ci * Get current firmware resource counts. 29458c2ecf20Sopenharmony_ci * 29468c2ecf20Sopenharmony_ci * Input: 29478c2ecf20Sopenharmony_ci * ha = adapter block pointer. 29488c2ecf20Sopenharmony_ci * 29498c2ecf20Sopenharmony_ci * Returns: 29508c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 29518c2ecf20Sopenharmony_ci * 29528c2ecf20Sopenharmony_ci * Context: 29538c2ecf20Sopenharmony_ci * Kernel context. 29548c2ecf20Sopenharmony_ci */ 29558c2ecf20Sopenharmony_ciint 29568c2ecf20Sopenharmony_ciqla2x00_get_resource_cnts(scsi_qla_host_t *vha) 29578c2ecf20Sopenharmony_ci{ 29588c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 29598c2ecf20Sopenharmony_ci int rval; 29608c2ecf20Sopenharmony_ci mbx_cmd_t mc; 29618c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 29628c2ecf20Sopenharmony_ci 29638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c, 29648c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 29658c2ecf20Sopenharmony_ci 29668c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; 29678c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 29688c2ecf20Sopenharmony_ci mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 29698c2ecf20Sopenharmony_ci if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || 29708c2ecf20Sopenharmony_ci IS_QLA27XX(ha) || IS_QLA28XX(ha)) 29718c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_12; 29728c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 29738c2ecf20Sopenharmony_ci mcp->flags = 0; 29748c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 29758c2ecf20Sopenharmony_ci 29768c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 29778c2ecf20Sopenharmony_ci /*EMPTY*/ 29788c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x107d, 29798c2ecf20Sopenharmony_ci "Failed mb[0]=%x.\n", mcp->mb[0]); 29808c2ecf20Sopenharmony_ci } else { 29818c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e, 29828c2ecf20Sopenharmony_ci "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x " 29838c2ecf20Sopenharmony_ci "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2], 29848c2ecf20Sopenharmony_ci mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10], 29858c2ecf20Sopenharmony_ci mcp->mb[11], mcp->mb[12]); 29868c2ecf20Sopenharmony_ci 29878c2ecf20Sopenharmony_ci ha->orig_fw_tgt_xcb_count = mcp->mb[1]; 29888c2ecf20Sopenharmony_ci ha->cur_fw_tgt_xcb_count = mcp->mb[2]; 29898c2ecf20Sopenharmony_ci ha->cur_fw_xcb_count = mcp->mb[3]; 29908c2ecf20Sopenharmony_ci ha->orig_fw_xcb_count = mcp->mb[6]; 29918c2ecf20Sopenharmony_ci ha->cur_fw_iocb_count = mcp->mb[7]; 29928c2ecf20Sopenharmony_ci ha->orig_fw_iocb_count = mcp->mb[10]; 29938c2ecf20Sopenharmony_ci if (ha->flags.npiv_supported) 29948c2ecf20Sopenharmony_ci ha->max_npiv_vports = mcp->mb[11]; 29958c2ecf20Sopenharmony_ci if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) 29968c2ecf20Sopenharmony_ci ha->fw_max_fcf_count = mcp->mb[12]; 29978c2ecf20Sopenharmony_ci } 29988c2ecf20Sopenharmony_ci 29998c2ecf20Sopenharmony_ci return (rval); 30008c2ecf20Sopenharmony_ci} 30018c2ecf20Sopenharmony_ci 30028c2ecf20Sopenharmony_ci/* 30038c2ecf20Sopenharmony_ci * qla2x00_get_fcal_position_map 30048c2ecf20Sopenharmony_ci * Get FCAL (LILP) position map using mailbox command 30058c2ecf20Sopenharmony_ci * 30068c2ecf20Sopenharmony_ci * Input: 30078c2ecf20Sopenharmony_ci * ha = adapter state pointer. 30088c2ecf20Sopenharmony_ci * pos_map = buffer pointer (can be NULL). 30098c2ecf20Sopenharmony_ci * 30108c2ecf20Sopenharmony_ci * Returns: 30118c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 30128c2ecf20Sopenharmony_ci * 30138c2ecf20Sopenharmony_ci * Context: 30148c2ecf20Sopenharmony_ci * Kernel context. 30158c2ecf20Sopenharmony_ci */ 30168c2ecf20Sopenharmony_ciint 30178c2ecf20Sopenharmony_ciqla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map, 30188c2ecf20Sopenharmony_ci u8 *num_entries) 30198c2ecf20Sopenharmony_ci{ 30208c2ecf20Sopenharmony_ci int rval; 30218c2ecf20Sopenharmony_ci mbx_cmd_t mc; 30228c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 30238c2ecf20Sopenharmony_ci char *pmap; 30248c2ecf20Sopenharmony_ci dma_addr_t pmap_dma; 30258c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 30268c2ecf20Sopenharmony_ci 30278c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f, 30288c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 30298c2ecf20Sopenharmony_ci 30308c2ecf20Sopenharmony_ci pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma); 30318c2ecf20Sopenharmony_ci if (pmap == NULL) { 30328c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1080, 30338c2ecf20Sopenharmony_ci "Memory alloc failed.\n"); 30348c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 30358c2ecf20Sopenharmony_ci } 30368c2ecf20Sopenharmony_ci 30378c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 30388c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(pmap_dma); 30398c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(pmap_dma); 30408c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(pmap_dma)); 30418c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(pmap_dma)); 30428c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 30438c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 30448c2ecf20Sopenharmony_ci mcp->buf_size = FCAL_MAP_SIZE; 30458c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_IN; 30468c2ecf20Sopenharmony_ci mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 30478c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) { 30508c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081, 30518c2ecf20Sopenharmony_ci "mb0/mb1=%x/%X FC/AL position map size (%x).\n", 30528c2ecf20Sopenharmony_ci mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]); 30538c2ecf20Sopenharmony_ci ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d, 30548c2ecf20Sopenharmony_ci pmap, pmap[0] + 1); 30558c2ecf20Sopenharmony_ci 30568c2ecf20Sopenharmony_ci if (pos_map) 30578c2ecf20Sopenharmony_ci memcpy(pos_map, pmap, FCAL_MAP_SIZE); 30588c2ecf20Sopenharmony_ci if (num_entries) 30598c2ecf20Sopenharmony_ci *num_entries = pmap[0]; 30608c2ecf20Sopenharmony_ci } 30618c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, pmap, pmap_dma); 30628c2ecf20Sopenharmony_ci 30638c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 30648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval); 30658c2ecf20Sopenharmony_ci } else { 30668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083, 30678c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 30688c2ecf20Sopenharmony_ci } 30698c2ecf20Sopenharmony_ci 30708c2ecf20Sopenharmony_ci return rval; 30718c2ecf20Sopenharmony_ci} 30728c2ecf20Sopenharmony_ci 30738c2ecf20Sopenharmony_ci/* 30748c2ecf20Sopenharmony_ci * qla2x00_get_link_status 30758c2ecf20Sopenharmony_ci * 30768c2ecf20Sopenharmony_ci * Input: 30778c2ecf20Sopenharmony_ci * ha = adapter block pointer. 30788c2ecf20Sopenharmony_ci * loop_id = device loop ID. 30798c2ecf20Sopenharmony_ci * ret_buf = pointer to link status return buffer. 30808c2ecf20Sopenharmony_ci * 30818c2ecf20Sopenharmony_ci * Returns: 30828c2ecf20Sopenharmony_ci * 0 = success. 30838c2ecf20Sopenharmony_ci * BIT_0 = mem alloc error. 30848c2ecf20Sopenharmony_ci * BIT_1 = mailbox error. 30858c2ecf20Sopenharmony_ci */ 30868c2ecf20Sopenharmony_ciint 30878c2ecf20Sopenharmony_ciqla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id, 30888c2ecf20Sopenharmony_ci struct link_statistics *stats, dma_addr_t stats_dma) 30898c2ecf20Sopenharmony_ci{ 30908c2ecf20Sopenharmony_ci int rval; 30918c2ecf20Sopenharmony_ci mbx_cmd_t mc; 30928c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 30938c2ecf20Sopenharmony_ci uint32_t *iter = (uint32_t *)stats; 30948c2ecf20Sopenharmony_ci ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter); 30958c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 30968c2ecf20Sopenharmony_ci 30978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084, 30988c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 30998c2ecf20Sopenharmony_ci 31008c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_LINK_STATUS; 31018c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(stats_dma)); 31028c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(stats_dma)); 31038c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(stats_dma)); 31048c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(stats_dma)); 31058c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 31068c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 31078c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(ha)) { 31088c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 31098c2ecf20Sopenharmony_ci mcp->mb[4] = 0; 31108c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 31118c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10|MBX_4|MBX_1; 31128c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 31138c2ecf20Sopenharmony_ci } else if (HAS_EXTENDED_IDS(ha)) { 31148c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 31158c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 31168c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10|MBX_1; 31178c2ecf20Sopenharmony_ci } else { 31188c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id << 8; 31198c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_1; 31208c2ecf20Sopenharmony_ci } 31218c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 31228c2ecf20Sopenharmony_ci mcp->flags = IOCTL_CMD; 31238c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 31248c2ecf20Sopenharmony_ci 31258c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) { 31268c2ecf20Sopenharmony_ci if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 31278c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1085, 31288c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 31298c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 31308c2ecf20Sopenharmony_ci } else { 31318c2ecf20Sopenharmony_ci /* Re-endianize - firmware data is le32. */ 31328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086, 31338c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 31348c2ecf20Sopenharmony_ci for ( ; dwords--; iter++) 31358c2ecf20Sopenharmony_ci le32_to_cpus(iter); 31368c2ecf20Sopenharmony_ci } 31378c2ecf20Sopenharmony_ci } else { 31388c2ecf20Sopenharmony_ci /* Failed. */ 31398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval); 31408c2ecf20Sopenharmony_ci } 31418c2ecf20Sopenharmony_ci 31428c2ecf20Sopenharmony_ci return rval; 31438c2ecf20Sopenharmony_ci} 31448c2ecf20Sopenharmony_ci 31458c2ecf20Sopenharmony_ciint 31468c2ecf20Sopenharmony_ciqla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, 31478c2ecf20Sopenharmony_ci dma_addr_t stats_dma, uint16_t options) 31488c2ecf20Sopenharmony_ci{ 31498c2ecf20Sopenharmony_ci int rval; 31508c2ecf20Sopenharmony_ci mbx_cmd_t mc; 31518c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 31528c2ecf20Sopenharmony_ci uint32_t *iter = (uint32_t *)stats; 31538c2ecf20Sopenharmony_ci ushort dwords = sizeof(*stats)/sizeof(*iter); 31548c2ecf20Sopenharmony_ci 31558c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, 31568c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 31578c2ecf20Sopenharmony_ci 31588c2ecf20Sopenharmony_ci memset(&mc, 0, sizeof(mc)); 31598c2ecf20Sopenharmony_ci mc.mb[0] = MBC_GET_LINK_PRIV_STATS; 31608c2ecf20Sopenharmony_ci mc.mb[2] = MSW(LSD(stats_dma)); 31618c2ecf20Sopenharmony_ci mc.mb[3] = LSW(LSD(stats_dma)); 31628c2ecf20Sopenharmony_ci mc.mb[6] = MSW(MSD(stats_dma)); 31638c2ecf20Sopenharmony_ci mc.mb[7] = LSW(MSD(stats_dma)); 31648c2ecf20Sopenharmony_ci mc.mb[8] = dwords; 31658c2ecf20Sopenharmony_ci mc.mb[9] = vha->vp_idx; 31668c2ecf20Sopenharmony_ci mc.mb[10] = options; 31678c2ecf20Sopenharmony_ci 31688c2ecf20Sopenharmony_ci rval = qla24xx_send_mb_cmd(vha, &mc); 31698c2ecf20Sopenharmony_ci 31708c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) { 31718c2ecf20Sopenharmony_ci if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 31728c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1089, 31738c2ecf20Sopenharmony_ci "Failed mb[0]=%x.\n", mcp->mb[0]); 31748c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 31758c2ecf20Sopenharmony_ci } else { 31768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a, 31778c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 31788c2ecf20Sopenharmony_ci /* Re-endianize - firmware data is le32. */ 31798c2ecf20Sopenharmony_ci for ( ; dwords--; iter++) 31808c2ecf20Sopenharmony_ci le32_to_cpus(iter); 31818c2ecf20Sopenharmony_ci } 31828c2ecf20Sopenharmony_ci } else { 31838c2ecf20Sopenharmony_ci /* Failed. */ 31848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval); 31858c2ecf20Sopenharmony_ci } 31868c2ecf20Sopenharmony_ci 31878c2ecf20Sopenharmony_ci return rval; 31888c2ecf20Sopenharmony_ci} 31898c2ecf20Sopenharmony_ci 31908c2ecf20Sopenharmony_ciint 31918c2ecf20Sopenharmony_ciqla24xx_abort_command(srb_t *sp) 31928c2ecf20Sopenharmony_ci{ 31938c2ecf20Sopenharmony_ci int rval; 31948c2ecf20Sopenharmony_ci unsigned long flags = 0; 31958c2ecf20Sopenharmony_ci 31968c2ecf20Sopenharmony_ci struct abort_entry_24xx *abt; 31978c2ecf20Sopenharmony_ci dma_addr_t abt_dma; 31988c2ecf20Sopenharmony_ci uint32_t handle; 31998c2ecf20Sopenharmony_ci fc_port_t *fcport = sp->fcport; 32008c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = fcport->vha; 32018c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 32028c2ecf20Sopenharmony_ci struct req_que *req = vha->req; 32038c2ecf20Sopenharmony_ci struct qla_qpair *qpair = sp->qpair; 32048c2ecf20Sopenharmony_ci 32058c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, 32068c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 32078c2ecf20Sopenharmony_ci 32088c2ecf20Sopenharmony_ci if (sp->qpair) 32098c2ecf20Sopenharmony_ci req = sp->qpair->req; 32108c2ecf20Sopenharmony_ci else 32118c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 32128c2ecf20Sopenharmony_ci 32138c2ecf20Sopenharmony_ci if (ql2xasynctmfenable) 32148c2ecf20Sopenharmony_ci return qla24xx_async_abort_command(sp); 32158c2ecf20Sopenharmony_ci 32168c2ecf20Sopenharmony_ci spin_lock_irqsave(qpair->qp_lock_ptr, flags); 32178c2ecf20Sopenharmony_ci for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 32188c2ecf20Sopenharmony_ci if (req->outstanding_cmds[handle] == sp) 32198c2ecf20Sopenharmony_ci break; 32208c2ecf20Sopenharmony_ci } 32218c2ecf20Sopenharmony_ci spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 32228c2ecf20Sopenharmony_ci if (handle == req->num_outstanding_cmds) { 32238c2ecf20Sopenharmony_ci /* Command not found. */ 32248c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 32258c2ecf20Sopenharmony_ci } 32268c2ecf20Sopenharmony_ci 32278c2ecf20Sopenharmony_ci abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma); 32288c2ecf20Sopenharmony_ci if (abt == NULL) { 32298c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x108d, 32308c2ecf20Sopenharmony_ci "Failed to allocate abort IOCB.\n"); 32318c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 32328c2ecf20Sopenharmony_ci } 32338c2ecf20Sopenharmony_ci 32348c2ecf20Sopenharmony_ci abt->entry_type = ABORT_IOCB_TYPE; 32358c2ecf20Sopenharmony_ci abt->entry_count = 1; 32368c2ecf20Sopenharmony_ci abt->handle = make_handle(req->id, abt->handle); 32378c2ecf20Sopenharmony_ci abt->nport_handle = cpu_to_le16(fcport->loop_id); 32388c2ecf20Sopenharmony_ci abt->handle_to_abort = make_handle(req->id, handle); 32398c2ecf20Sopenharmony_ci abt->port_id[0] = fcport->d_id.b.al_pa; 32408c2ecf20Sopenharmony_ci abt->port_id[1] = fcport->d_id.b.area; 32418c2ecf20Sopenharmony_ci abt->port_id[2] = fcport->d_id.b.domain; 32428c2ecf20Sopenharmony_ci abt->vp_index = fcport->vha->vp_idx; 32438c2ecf20Sopenharmony_ci 32448c2ecf20Sopenharmony_ci abt->req_que_no = cpu_to_le16(req->id); 32458c2ecf20Sopenharmony_ci 32468c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0); 32478c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 32488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x108e, 32498c2ecf20Sopenharmony_ci "Failed to issue IOCB (%x).\n", rval); 32508c2ecf20Sopenharmony_ci } else if (abt->entry_status != 0) { 32518c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x108f, 32528c2ecf20Sopenharmony_ci "Failed to complete IOCB -- error status (%x).\n", 32538c2ecf20Sopenharmony_ci abt->entry_status); 32548c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 32558c2ecf20Sopenharmony_ci } else if (abt->nport_handle != cpu_to_le16(0)) { 32568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1090, 32578c2ecf20Sopenharmony_ci "Failed to complete IOCB -- completion status (%x).\n", 32588c2ecf20Sopenharmony_ci le16_to_cpu(abt->nport_handle)); 32598c2ecf20Sopenharmony_ci if (abt->nport_handle == cpu_to_le16(CS_IOCB_ERROR)) 32608c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_PARAMETER_ERROR; 32618c2ecf20Sopenharmony_ci else 32628c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 32638c2ecf20Sopenharmony_ci } else { 32648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, 32658c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 32668c2ecf20Sopenharmony_ci } 32678c2ecf20Sopenharmony_ci 32688c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, abt, abt_dma); 32698c2ecf20Sopenharmony_ci 32708c2ecf20Sopenharmony_ci return rval; 32718c2ecf20Sopenharmony_ci} 32728c2ecf20Sopenharmony_ci 32738c2ecf20Sopenharmony_cistruct tsk_mgmt_cmd { 32748c2ecf20Sopenharmony_ci union { 32758c2ecf20Sopenharmony_ci struct tsk_mgmt_entry tsk; 32768c2ecf20Sopenharmony_ci struct sts_entry_24xx sts; 32778c2ecf20Sopenharmony_ci } p; 32788c2ecf20Sopenharmony_ci}; 32798c2ecf20Sopenharmony_ci 32808c2ecf20Sopenharmony_cistatic int 32818c2ecf20Sopenharmony_ci__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, 32828c2ecf20Sopenharmony_ci uint64_t l, int tag) 32838c2ecf20Sopenharmony_ci{ 32848c2ecf20Sopenharmony_ci int rval, rval2; 32858c2ecf20Sopenharmony_ci struct tsk_mgmt_cmd *tsk; 32868c2ecf20Sopenharmony_ci struct sts_entry_24xx *sts; 32878c2ecf20Sopenharmony_ci dma_addr_t tsk_dma; 32888c2ecf20Sopenharmony_ci scsi_qla_host_t *vha; 32898c2ecf20Sopenharmony_ci struct qla_hw_data *ha; 32908c2ecf20Sopenharmony_ci struct req_que *req; 32918c2ecf20Sopenharmony_ci struct qla_qpair *qpair; 32928c2ecf20Sopenharmony_ci 32938c2ecf20Sopenharmony_ci vha = fcport->vha; 32948c2ecf20Sopenharmony_ci ha = vha->hw; 32958c2ecf20Sopenharmony_ci req = vha->req; 32968c2ecf20Sopenharmony_ci 32978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092, 32988c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 32998c2ecf20Sopenharmony_ci 33008c2ecf20Sopenharmony_ci if (vha->vp_idx && vha->qpair) { 33018c2ecf20Sopenharmony_ci /* NPIV port */ 33028c2ecf20Sopenharmony_ci qpair = vha->qpair; 33038c2ecf20Sopenharmony_ci req = qpair->req; 33048c2ecf20Sopenharmony_ci } 33058c2ecf20Sopenharmony_ci 33068c2ecf20Sopenharmony_ci tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); 33078c2ecf20Sopenharmony_ci if (tsk == NULL) { 33088c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1093, 33098c2ecf20Sopenharmony_ci "Failed to allocate task management IOCB.\n"); 33108c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 33118c2ecf20Sopenharmony_ci } 33128c2ecf20Sopenharmony_ci 33138c2ecf20Sopenharmony_ci tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; 33148c2ecf20Sopenharmony_ci tsk->p.tsk.entry_count = 1; 33158c2ecf20Sopenharmony_ci tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle); 33168c2ecf20Sopenharmony_ci tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); 33178c2ecf20Sopenharmony_ci tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 33188c2ecf20Sopenharmony_ci tsk->p.tsk.control_flags = cpu_to_le32(type); 33198c2ecf20Sopenharmony_ci tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; 33208c2ecf20Sopenharmony_ci tsk->p.tsk.port_id[1] = fcport->d_id.b.area; 33218c2ecf20Sopenharmony_ci tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; 33228c2ecf20Sopenharmony_ci tsk->p.tsk.vp_index = fcport->vha->vp_idx; 33238c2ecf20Sopenharmony_ci if (type == TCF_LUN_RESET) { 33248c2ecf20Sopenharmony_ci int_to_scsilun(l, &tsk->p.tsk.lun); 33258c2ecf20Sopenharmony_ci host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, 33268c2ecf20Sopenharmony_ci sizeof(tsk->p.tsk.lun)); 33278c2ecf20Sopenharmony_ci } 33288c2ecf20Sopenharmony_ci 33298c2ecf20Sopenharmony_ci sts = &tsk->p.sts; 33308c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0); 33318c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 33328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1094, 33338c2ecf20Sopenharmony_ci "Failed to issue %s reset IOCB (%x).\n", name, rval); 33348c2ecf20Sopenharmony_ci } else if (sts->entry_status != 0) { 33358c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1095, 33368c2ecf20Sopenharmony_ci "Failed to complete IOCB -- error status (%x).\n", 33378c2ecf20Sopenharmony_ci sts->entry_status); 33388c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 33398c2ecf20Sopenharmony_ci } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) { 33408c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1096, 33418c2ecf20Sopenharmony_ci "Failed to complete IOCB -- completion status (%x).\n", 33428c2ecf20Sopenharmony_ci le16_to_cpu(sts->comp_status)); 33438c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 33448c2ecf20Sopenharmony_ci } else if (le16_to_cpu(sts->scsi_status) & 33458c2ecf20Sopenharmony_ci SS_RESPONSE_INFO_LEN_VALID) { 33468c2ecf20Sopenharmony_ci if (le32_to_cpu(sts->rsp_data_len) < 4) { 33478c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097, 33488c2ecf20Sopenharmony_ci "Ignoring inconsistent data length -- not enough " 33498c2ecf20Sopenharmony_ci "response info (%d).\n", 33508c2ecf20Sopenharmony_ci le32_to_cpu(sts->rsp_data_len)); 33518c2ecf20Sopenharmony_ci } else if (sts->data[3]) { 33528c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1098, 33538c2ecf20Sopenharmony_ci "Failed to complete IOCB -- response (%x).\n", 33548c2ecf20Sopenharmony_ci sts->data[3]); 33558c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 33568c2ecf20Sopenharmony_ci } 33578c2ecf20Sopenharmony_ci } 33588c2ecf20Sopenharmony_ci 33598c2ecf20Sopenharmony_ci /* Issue marker IOCB. */ 33608c2ecf20Sopenharmony_ci rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l, 33618c2ecf20Sopenharmony_ci type == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID); 33628c2ecf20Sopenharmony_ci if (rval2 != QLA_SUCCESS) { 33638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1099, 33648c2ecf20Sopenharmony_ci "Failed to issue marker IOCB (%x).\n", rval2); 33658c2ecf20Sopenharmony_ci } else { 33668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a, 33678c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 33688c2ecf20Sopenharmony_ci } 33698c2ecf20Sopenharmony_ci 33708c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); 33718c2ecf20Sopenharmony_ci 33728c2ecf20Sopenharmony_ci return rval; 33738c2ecf20Sopenharmony_ci} 33748c2ecf20Sopenharmony_ci 33758c2ecf20Sopenharmony_ciint 33768c2ecf20Sopenharmony_ciqla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag) 33778c2ecf20Sopenharmony_ci{ 33788c2ecf20Sopenharmony_ci struct qla_hw_data *ha = fcport->vha->hw; 33798c2ecf20Sopenharmony_ci 33808c2ecf20Sopenharmony_ci if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) 33818c2ecf20Sopenharmony_ci return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag); 33828c2ecf20Sopenharmony_ci 33838c2ecf20Sopenharmony_ci return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag); 33848c2ecf20Sopenharmony_ci} 33858c2ecf20Sopenharmony_ci 33868c2ecf20Sopenharmony_ciint 33878c2ecf20Sopenharmony_ciqla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag) 33888c2ecf20Sopenharmony_ci{ 33898c2ecf20Sopenharmony_ci struct qla_hw_data *ha = fcport->vha->hw; 33908c2ecf20Sopenharmony_ci 33918c2ecf20Sopenharmony_ci if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) 33928c2ecf20Sopenharmony_ci return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag); 33938c2ecf20Sopenharmony_ci 33948c2ecf20Sopenharmony_ci return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag); 33958c2ecf20Sopenharmony_ci} 33968c2ecf20Sopenharmony_ci 33978c2ecf20Sopenharmony_ciint 33988c2ecf20Sopenharmony_ciqla2x00_system_error(scsi_qla_host_t *vha) 33998c2ecf20Sopenharmony_ci{ 34008c2ecf20Sopenharmony_ci int rval; 34018c2ecf20Sopenharmony_ci mbx_cmd_t mc; 34028c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 34038c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 34048c2ecf20Sopenharmony_ci 34058c2ecf20Sopenharmony_ci if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) 34068c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 34078c2ecf20Sopenharmony_ci 34088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b, 34098c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 34108c2ecf20Sopenharmony_ci 34118c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; 34128c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 34138c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 34148c2ecf20Sopenharmony_ci mcp->tov = 5; 34158c2ecf20Sopenharmony_ci mcp->flags = 0; 34168c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 34178c2ecf20Sopenharmony_ci 34188c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 34198c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval); 34208c2ecf20Sopenharmony_ci } else { 34218c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d, 34228c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 34238c2ecf20Sopenharmony_ci } 34248c2ecf20Sopenharmony_ci 34258c2ecf20Sopenharmony_ci return rval; 34268c2ecf20Sopenharmony_ci} 34278c2ecf20Sopenharmony_ci 34288c2ecf20Sopenharmony_ciint 34298c2ecf20Sopenharmony_ciqla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data) 34308c2ecf20Sopenharmony_ci{ 34318c2ecf20Sopenharmony_ci int rval; 34328c2ecf20Sopenharmony_ci mbx_cmd_t mc; 34338c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 34348c2ecf20Sopenharmony_ci 34358c2ecf20Sopenharmony_ci if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && 34368c2ecf20Sopenharmony_ci !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 34378c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 34388c2ecf20Sopenharmony_ci 34398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182, 34408c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 34418c2ecf20Sopenharmony_ci 34428c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_WRITE_SERDES; 34438c2ecf20Sopenharmony_ci mcp->mb[1] = addr; 34448c2ecf20Sopenharmony_ci if (IS_QLA2031(vha->hw)) 34458c2ecf20Sopenharmony_ci mcp->mb[2] = data & 0xff; 34468c2ecf20Sopenharmony_ci else 34478c2ecf20Sopenharmony_ci mcp->mb[2] = data; 34488c2ecf20Sopenharmony_ci 34498c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 34508c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 34518c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 34528c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 34538c2ecf20Sopenharmony_ci mcp->flags = 0; 34548c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 34558c2ecf20Sopenharmony_ci 34568c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 34578c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1183, 34588c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 34598c2ecf20Sopenharmony_ci } else { 34608c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184, 34618c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 34628c2ecf20Sopenharmony_ci } 34638c2ecf20Sopenharmony_ci 34648c2ecf20Sopenharmony_ci return rval; 34658c2ecf20Sopenharmony_ci} 34668c2ecf20Sopenharmony_ci 34678c2ecf20Sopenharmony_ciint 34688c2ecf20Sopenharmony_ciqla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) 34698c2ecf20Sopenharmony_ci{ 34708c2ecf20Sopenharmony_ci int rval; 34718c2ecf20Sopenharmony_ci mbx_cmd_t mc; 34728c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 34738c2ecf20Sopenharmony_ci 34748c2ecf20Sopenharmony_ci if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && 34758c2ecf20Sopenharmony_ci !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 34768c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 34778c2ecf20Sopenharmony_ci 34788c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185, 34798c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 34808c2ecf20Sopenharmony_ci 34818c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_READ_SERDES; 34828c2ecf20Sopenharmony_ci mcp->mb[1] = addr; 34838c2ecf20Sopenharmony_ci mcp->mb[3] = 0; 34848c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_1|MBX_0; 34858c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 34868c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 34878c2ecf20Sopenharmony_ci mcp->flags = 0; 34888c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 34898c2ecf20Sopenharmony_ci 34908c2ecf20Sopenharmony_ci if (IS_QLA2031(vha->hw)) 34918c2ecf20Sopenharmony_ci *data = mcp->mb[1] & 0xff; 34928c2ecf20Sopenharmony_ci else 34938c2ecf20Sopenharmony_ci *data = mcp->mb[1]; 34948c2ecf20Sopenharmony_ci 34958c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 34968c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1186, 34978c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 34988c2ecf20Sopenharmony_ci } else { 34998c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187, 35008c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 35018c2ecf20Sopenharmony_ci } 35028c2ecf20Sopenharmony_ci 35038c2ecf20Sopenharmony_ci return rval; 35048c2ecf20Sopenharmony_ci} 35058c2ecf20Sopenharmony_ci 35068c2ecf20Sopenharmony_ciint 35078c2ecf20Sopenharmony_ciqla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data) 35088c2ecf20Sopenharmony_ci{ 35098c2ecf20Sopenharmony_ci int rval; 35108c2ecf20Sopenharmony_ci mbx_cmd_t mc; 35118c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 35128c2ecf20Sopenharmony_ci 35138c2ecf20Sopenharmony_ci if (!IS_QLA8044(vha->hw)) 35148c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 35158c2ecf20Sopenharmony_ci 35168c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0, 35178c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 35188c2ecf20Sopenharmony_ci 35198c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; 35208c2ecf20Sopenharmony_ci mcp->mb[1] = HCS_WRITE_SERDES; 35218c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(addr); 35228c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(addr); 35238c2ecf20Sopenharmony_ci mcp->mb[5] = LSW(data); 35248c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(data); 35258c2ecf20Sopenharmony_ci mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; 35268c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 35278c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 35288c2ecf20Sopenharmony_ci mcp->flags = 0; 35298c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 35308c2ecf20Sopenharmony_ci 35318c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 35328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x11a1, 35338c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 35348c2ecf20Sopenharmony_ci } else { 35358c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188, 35368c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 35378c2ecf20Sopenharmony_ci } 35388c2ecf20Sopenharmony_ci 35398c2ecf20Sopenharmony_ci return rval; 35408c2ecf20Sopenharmony_ci} 35418c2ecf20Sopenharmony_ci 35428c2ecf20Sopenharmony_ciint 35438c2ecf20Sopenharmony_ciqla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data) 35448c2ecf20Sopenharmony_ci{ 35458c2ecf20Sopenharmony_ci int rval; 35468c2ecf20Sopenharmony_ci mbx_cmd_t mc; 35478c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 35488c2ecf20Sopenharmony_ci 35498c2ecf20Sopenharmony_ci if (!IS_QLA8044(vha->hw)) 35508c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 35518c2ecf20Sopenharmony_ci 35528c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189, 35538c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 35548c2ecf20Sopenharmony_ci 35558c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; 35568c2ecf20Sopenharmony_ci mcp->mb[1] = HCS_READ_SERDES; 35578c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(addr); 35588c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(addr); 35598c2ecf20Sopenharmony_ci mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0; 35608c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 35618c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 35628c2ecf20Sopenharmony_ci mcp->flags = 0; 35638c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 35648c2ecf20Sopenharmony_ci 35658c2ecf20Sopenharmony_ci *data = mcp->mb[2] << 16 | mcp->mb[1]; 35668c2ecf20Sopenharmony_ci 35678c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 35688c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x118a, 35698c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 35708c2ecf20Sopenharmony_ci } else { 35718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b, 35728c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 35738c2ecf20Sopenharmony_ci } 35748c2ecf20Sopenharmony_ci 35758c2ecf20Sopenharmony_ci return rval; 35768c2ecf20Sopenharmony_ci} 35778c2ecf20Sopenharmony_ci 35788c2ecf20Sopenharmony_ci/** 35798c2ecf20Sopenharmony_ci * qla2x00_set_serdes_params() - 35808c2ecf20Sopenharmony_ci * @vha: HA context 35818c2ecf20Sopenharmony_ci * @sw_em_1g: serial link options 35828c2ecf20Sopenharmony_ci * @sw_em_2g: serial link options 35838c2ecf20Sopenharmony_ci * @sw_em_4g: serial link options 35848c2ecf20Sopenharmony_ci * 35858c2ecf20Sopenharmony_ci * Returns 35868c2ecf20Sopenharmony_ci */ 35878c2ecf20Sopenharmony_ciint 35888c2ecf20Sopenharmony_ciqla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g, 35898c2ecf20Sopenharmony_ci uint16_t sw_em_2g, uint16_t sw_em_4g) 35908c2ecf20Sopenharmony_ci{ 35918c2ecf20Sopenharmony_ci int rval; 35928c2ecf20Sopenharmony_ci mbx_cmd_t mc; 35938c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 35948c2ecf20Sopenharmony_ci 35958c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e, 35968c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 35978c2ecf20Sopenharmony_ci 35988c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SERDES_PARAMS; 35998c2ecf20Sopenharmony_ci mcp->mb[1] = BIT_0; 36008c2ecf20Sopenharmony_ci mcp->mb[2] = sw_em_1g | BIT_15; 36018c2ecf20Sopenharmony_ci mcp->mb[3] = sw_em_2g | BIT_15; 36028c2ecf20Sopenharmony_ci mcp->mb[4] = sw_em_4g | BIT_15; 36038c2ecf20Sopenharmony_ci mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 36048c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 36058c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 36068c2ecf20Sopenharmony_ci mcp->flags = 0; 36078c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 36088c2ecf20Sopenharmony_ci 36098c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 36108c2ecf20Sopenharmony_ci /*EMPTY*/ 36118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x109f, 36128c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 36138c2ecf20Sopenharmony_ci } else { 36148c2ecf20Sopenharmony_ci /*EMPTY*/ 36158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0, 36168c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 36178c2ecf20Sopenharmony_ci } 36188c2ecf20Sopenharmony_ci 36198c2ecf20Sopenharmony_ci return rval; 36208c2ecf20Sopenharmony_ci} 36218c2ecf20Sopenharmony_ci 36228c2ecf20Sopenharmony_ciint 36238c2ecf20Sopenharmony_ciqla2x00_stop_firmware(scsi_qla_host_t *vha) 36248c2ecf20Sopenharmony_ci{ 36258c2ecf20Sopenharmony_ci int rval; 36268c2ecf20Sopenharmony_ci mbx_cmd_t mc; 36278c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 36288c2ecf20Sopenharmony_ci 36298c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 36308c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 36318c2ecf20Sopenharmony_ci 36328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1, 36338c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 36348c2ecf20Sopenharmony_ci 36358c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_STOP_FIRMWARE; 36368c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 36378c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 36388c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 36398c2ecf20Sopenharmony_ci mcp->tov = 5; 36408c2ecf20Sopenharmony_ci mcp->flags = 0; 36418c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 36428c2ecf20Sopenharmony_ci 36438c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 36448c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval); 36458c2ecf20Sopenharmony_ci if (mcp->mb[0] == MBS_INVALID_COMMAND) 36468c2ecf20Sopenharmony_ci rval = QLA_INVALID_COMMAND; 36478c2ecf20Sopenharmony_ci } else { 36488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3, 36498c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 36508c2ecf20Sopenharmony_ci } 36518c2ecf20Sopenharmony_ci 36528c2ecf20Sopenharmony_ci return rval; 36538c2ecf20Sopenharmony_ci} 36548c2ecf20Sopenharmony_ci 36558c2ecf20Sopenharmony_ciint 36568c2ecf20Sopenharmony_ciqla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, 36578c2ecf20Sopenharmony_ci uint16_t buffers) 36588c2ecf20Sopenharmony_ci{ 36598c2ecf20Sopenharmony_ci int rval; 36608c2ecf20Sopenharmony_ci mbx_cmd_t mc; 36618c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 36628c2ecf20Sopenharmony_ci 36638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4, 36648c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 36658c2ecf20Sopenharmony_ci 36668c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 36678c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 36688c2ecf20Sopenharmony_ci 36698c2ecf20Sopenharmony_ci if (unlikely(pci_channel_offline(vha->hw->pdev))) 36708c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 36718c2ecf20Sopenharmony_ci 36728c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TRACE_CONTROL; 36738c2ecf20Sopenharmony_ci mcp->mb[1] = TC_EFT_ENABLE; 36748c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(eft_dma); 36758c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(eft_dma); 36768c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(MSD(eft_dma)); 36778c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(MSD(eft_dma)); 36788c2ecf20Sopenharmony_ci mcp->mb[6] = buffers; 36798c2ecf20Sopenharmony_ci mcp->mb[7] = TC_AEN_DISABLE; 36808c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 36818c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 36828c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 36838c2ecf20Sopenharmony_ci mcp->flags = 0; 36848c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 36858c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 36868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10a5, 36878c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 36888c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 36898c2ecf20Sopenharmony_ci } else { 36908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6, 36918c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 36928c2ecf20Sopenharmony_ci } 36938c2ecf20Sopenharmony_ci 36948c2ecf20Sopenharmony_ci return rval; 36958c2ecf20Sopenharmony_ci} 36968c2ecf20Sopenharmony_ci 36978c2ecf20Sopenharmony_ciint 36988c2ecf20Sopenharmony_ciqla2x00_disable_eft_trace(scsi_qla_host_t *vha) 36998c2ecf20Sopenharmony_ci{ 37008c2ecf20Sopenharmony_ci int rval; 37018c2ecf20Sopenharmony_ci mbx_cmd_t mc; 37028c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 37038c2ecf20Sopenharmony_ci 37048c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7, 37058c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 37068c2ecf20Sopenharmony_ci 37078c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 37088c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 37098c2ecf20Sopenharmony_ci 37108c2ecf20Sopenharmony_ci if (unlikely(pci_channel_offline(vha->hw->pdev))) 37118c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 37128c2ecf20Sopenharmony_ci 37138c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TRACE_CONTROL; 37148c2ecf20Sopenharmony_ci mcp->mb[1] = TC_EFT_DISABLE; 37158c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 37168c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 37178c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 37188c2ecf20Sopenharmony_ci mcp->flags = 0; 37198c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 37208c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 37218c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10a8, 37228c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 37238c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 37248c2ecf20Sopenharmony_ci } else { 37258c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9, 37268c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 37278c2ecf20Sopenharmony_ci } 37288c2ecf20Sopenharmony_ci 37298c2ecf20Sopenharmony_ci return rval; 37308c2ecf20Sopenharmony_ci} 37318c2ecf20Sopenharmony_ci 37328c2ecf20Sopenharmony_ciint 37338c2ecf20Sopenharmony_ciqla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, 37348c2ecf20Sopenharmony_ci uint16_t buffers, uint16_t *mb, uint32_t *dwords) 37358c2ecf20Sopenharmony_ci{ 37368c2ecf20Sopenharmony_ci int rval; 37378c2ecf20Sopenharmony_ci mbx_cmd_t mc; 37388c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 37398c2ecf20Sopenharmony_ci 37408c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa, 37418c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 37428c2ecf20Sopenharmony_ci 37438c2ecf20Sopenharmony_ci if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && 37448c2ecf20Sopenharmony_ci !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && 37458c2ecf20Sopenharmony_ci !IS_QLA28XX(vha->hw)) 37468c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 37478c2ecf20Sopenharmony_ci 37488c2ecf20Sopenharmony_ci if (unlikely(pci_channel_offline(vha->hw->pdev))) 37498c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 37508c2ecf20Sopenharmony_ci 37518c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TRACE_CONTROL; 37528c2ecf20Sopenharmony_ci mcp->mb[1] = TC_FCE_ENABLE; 37538c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(fce_dma); 37548c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(fce_dma); 37558c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(MSD(fce_dma)); 37568c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(MSD(fce_dma)); 37578c2ecf20Sopenharmony_ci mcp->mb[6] = buffers; 37588c2ecf20Sopenharmony_ci mcp->mb[7] = TC_AEN_DISABLE; 37598c2ecf20Sopenharmony_ci mcp->mb[8] = 0; 37608c2ecf20Sopenharmony_ci mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE; 37618c2ecf20Sopenharmony_ci mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE; 37628c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| 37638c2ecf20Sopenharmony_ci MBX_1|MBX_0; 37648c2ecf20Sopenharmony_ci mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 37658c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 37668c2ecf20Sopenharmony_ci mcp->flags = 0; 37678c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 37688c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 37698c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ab, 37708c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 37718c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 37728c2ecf20Sopenharmony_ci } else { 37738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac, 37748c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 37758c2ecf20Sopenharmony_ci 37768c2ecf20Sopenharmony_ci if (mb) 37778c2ecf20Sopenharmony_ci memcpy(mb, mcp->mb, 8 * sizeof(*mb)); 37788c2ecf20Sopenharmony_ci if (dwords) 37798c2ecf20Sopenharmony_ci *dwords = buffers; 37808c2ecf20Sopenharmony_ci } 37818c2ecf20Sopenharmony_ci 37828c2ecf20Sopenharmony_ci return rval; 37838c2ecf20Sopenharmony_ci} 37848c2ecf20Sopenharmony_ci 37858c2ecf20Sopenharmony_ciint 37868c2ecf20Sopenharmony_ciqla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) 37878c2ecf20Sopenharmony_ci{ 37888c2ecf20Sopenharmony_ci int rval; 37898c2ecf20Sopenharmony_ci mbx_cmd_t mc; 37908c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 37918c2ecf20Sopenharmony_ci 37928c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad, 37938c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 37948c2ecf20Sopenharmony_ci 37958c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 37968c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 37978c2ecf20Sopenharmony_ci 37988c2ecf20Sopenharmony_ci if (unlikely(pci_channel_offline(vha->hw->pdev))) 37998c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 38008c2ecf20Sopenharmony_ci 38018c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TRACE_CONTROL; 38028c2ecf20Sopenharmony_ci mcp->mb[1] = TC_FCE_DISABLE; 38038c2ecf20Sopenharmony_ci mcp->mb[2] = TC_FCE_DISABLE_TRACE; 38048c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 38058c2ecf20Sopenharmony_ci mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| 38068c2ecf20Sopenharmony_ci MBX_1|MBX_0; 38078c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 38088c2ecf20Sopenharmony_ci mcp->flags = 0; 38098c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 38108c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 38118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ae, 38128c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 38138c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 38148c2ecf20Sopenharmony_ci } else { 38158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af, 38168c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 38178c2ecf20Sopenharmony_ci 38188c2ecf20Sopenharmony_ci if (wr) 38198c2ecf20Sopenharmony_ci *wr = (uint64_t) mcp->mb[5] << 48 | 38208c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[4] << 32 | 38218c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[3] << 16 | 38228c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[2]; 38238c2ecf20Sopenharmony_ci if (rd) 38248c2ecf20Sopenharmony_ci *rd = (uint64_t) mcp->mb[9] << 48 | 38258c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[8] << 32 | 38268c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[7] << 16 | 38278c2ecf20Sopenharmony_ci (uint64_t) mcp->mb[6]; 38288c2ecf20Sopenharmony_ci } 38298c2ecf20Sopenharmony_ci 38308c2ecf20Sopenharmony_ci return rval; 38318c2ecf20Sopenharmony_ci} 38328c2ecf20Sopenharmony_ci 38338c2ecf20Sopenharmony_ciint 38348c2ecf20Sopenharmony_ciqla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, 38358c2ecf20Sopenharmony_ci uint16_t *port_speed, uint16_t *mb) 38368c2ecf20Sopenharmony_ci{ 38378c2ecf20Sopenharmony_ci int rval; 38388c2ecf20Sopenharmony_ci mbx_cmd_t mc; 38398c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 38408c2ecf20Sopenharmony_ci 38418c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0, 38428c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 38438c2ecf20Sopenharmony_ci 38448c2ecf20Sopenharmony_ci if (!IS_IIDMA_CAPABLE(vha->hw)) 38458c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 38468c2ecf20Sopenharmony_ci 38478c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_PORT_PARAMS; 38488c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 38498c2ecf20Sopenharmony_ci mcp->mb[2] = mcp->mb[3] = 0; 38508c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 38518c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 38528c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_1|MBX_0; 38538c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 38548c2ecf20Sopenharmony_ci mcp->flags = 0; 38558c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 38568c2ecf20Sopenharmony_ci 38578c2ecf20Sopenharmony_ci /* Return mailbox statuses. */ 38588c2ecf20Sopenharmony_ci if (mb) { 38598c2ecf20Sopenharmony_ci mb[0] = mcp->mb[0]; 38608c2ecf20Sopenharmony_ci mb[1] = mcp->mb[1]; 38618c2ecf20Sopenharmony_ci mb[3] = mcp->mb[3]; 38628c2ecf20Sopenharmony_ci } 38638c2ecf20Sopenharmony_ci 38648c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 38658c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval); 38668c2ecf20Sopenharmony_ci } else { 38678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2, 38688c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 38698c2ecf20Sopenharmony_ci if (port_speed) 38708c2ecf20Sopenharmony_ci *port_speed = mcp->mb[3]; 38718c2ecf20Sopenharmony_ci } 38728c2ecf20Sopenharmony_ci 38738c2ecf20Sopenharmony_ci return rval; 38748c2ecf20Sopenharmony_ci} 38758c2ecf20Sopenharmony_ci 38768c2ecf20Sopenharmony_ciint 38778c2ecf20Sopenharmony_ciqla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, 38788c2ecf20Sopenharmony_ci uint16_t port_speed, uint16_t *mb) 38798c2ecf20Sopenharmony_ci{ 38808c2ecf20Sopenharmony_ci int rval; 38818c2ecf20Sopenharmony_ci mbx_cmd_t mc; 38828c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 38838c2ecf20Sopenharmony_ci 38848c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3, 38858c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 38868c2ecf20Sopenharmony_ci 38878c2ecf20Sopenharmony_ci if (!IS_IIDMA_CAPABLE(vha->hw)) 38888c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 38898c2ecf20Sopenharmony_ci 38908c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_PORT_PARAMS; 38918c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 38928c2ecf20Sopenharmony_ci mcp->mb[2] = BIT_0; 38938c2ecf20Sopenharmony_ci mcp->mb[3] = port_speed & 0x3F; 38948c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 38958c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 38968c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_1|MBX_0; 38978c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 38988c2ecf20Sopenharmony_ci mcp->flags = 0; 38998c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 39008c2ecf20Sopenharmony_ci 39018c2ecf20Sopenharmony_ci /* Return mailbox statuses. */ 39028c2ecf20Sopenharmony_ci if (mb) { 39038c2ecf20Sopenharmony_ci mb[0] = mcp->mb[0]; 39048c2ecf20Sopenharmony_ci mb[1] = mcp->mb[1]; 39058c2ecf20Sopenharmony_ci mb[3] = mcp->mb[3]; 39068c2ecf20Sopenharmony_ci } 39078c2ecf20Sopenharmony_ci 39088c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 39098c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10b4, 39108c2ecf20Sopenharmony_ci "Failed=%x.\n", rval); 39118c2ecf20Sopenharmony_ci } else { 39128c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5, 39138c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 39148c2ecf20Sopenharmony_ci } 39158c2ecf20Sopenharmony_ci 39168c2ecf20Sopenharmony_ci return rval; 39178c2ecf20Sopenharmony_ci} 39188c2ecf20Sopenharmony_ci 39198c2ecf20Sopenharmony_civoid 39208c2ecf20Sopenharmony_ciqla24xx_report_id_acquisition(scsi_qla_host_t *vha, 39218c2ecf20Sopenharmony_ci struct vp_rpt_id_entry_24xx *rptid_entry) 39228c2ecf20Sopenharmony_ci{ 39238c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 39248c2ecf20Sopenharmony_ci scsi_qla_host_t *vp = NULL; 39258c2ecf20Sopenharmony_ci unsigned long flags; 39268c2ecf20Sopenharmony_ci int found; 39278c2ecf20Sopenharmony_ci port_id_t id; 39288c2ecf20Sopenharmony_ci struct fc_port *fcport; 39298c2ecf20Sopenharmony_ci 39308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, 39318c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 39328c2ecf20Sopenharmony_ci 39338c2ecf20Sopenharmony_ci if (rptid_entry->entry_status != 0) 39348c2ecf20Sopenharmony_ci return; 39358c2ecf20Sopenharmony_ci 39368c2ecf20Sopenharmony_ci id.b.domain = rptid_entry->port_id[2]; 39378c2ecf20Sopenharmony_ci id.b.area = rptid_entry->port_id[1]; 39388c2ecf20Sopenharmony_ci id.b.al_pa = rptid_entry->port_id[0]; 39398c2ecf20Sopenharmony_ci id.b.rsvd_1 = 0; 39408c2ecf20Sopenharmony_ci ha->flags.n2n_ae = 0; 39418c2ecf20Sopenharmony_ci 39428c2ecf20Sopenharmony_ci if (rptid_entry->format == 0) { 39438c2ecf20Sopenharmony_ci /* loop */ 39448c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x10b7, 39458c2ecf20Sopenharmony_ci "Format 0 : Number of VPs setup %d, number of " 39468c2ecf20Sopenharmony_ci "VPs acquired %d.\n", rptid_entry->vp_setup, 39478c2ecf20Sopenharmony_ci rptid_entry->vp_acquired); 39488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x10b8, 39498c2ecf20Sopenharmony_ci "Primary port id %02x%02x%02x.\n", 39508c2ecf20Sopenharmony_ci rptid_entry->port_id[2], rptid_entry->port_id[1], 39518c2ecf20Sopenharmony_ci rptid_entry->port_id[0]); 39528c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_NL; 39538c2ecf20Sopenharmony_ci qlt_update_host_map(vha, id); 39548c2ecf20Sopenharmony_ci 39558c2ecf20Sopenharmony_ci } else if (rptid_entry->format == 1) { 39568c2ecf20Sopenharmony_ci /* fabric */ 39578c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x10b9, 39588c2ecf20Sopenharmony_ci "Format 1: VP[%d] enabled - status %d - with " 39598c2ecf20Sopenharmony_ci "port id %02x%02x%02x.\n", rptid_entry->vp_idx, 39608c2ecf20Sopenharmony_ci rptid_entry->vp_status, 39618c2ecf20Sopenharmony_ci rptid_entry->port_id[2], rptid_entry->port_id[1], 39628c2ecf20Sopenharmony_ci rptid_entry->port_id[0]); 39638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x5075, 39648c2ecf20Sopenharmony_ci "Format 1: Remote WWPN %8phC.\n", 39658c2ecf20Sopenharmony_ci rptid_entry->u.f1.port_name); 39668c2ecf20Sopenharmony_ci 39678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x5075, 39688c2ecf20Sopenharmony_ci "Format 1: WWPN %8phC.\n", 39698c2ecf20Sopenharmony_ci vha->port_name); 39708c2ecf20Sopenharmony_ci 39718c2ecf20Sopenharmony_ci switch (rptid_entry->u.f1.flags & TOPO_MASK) { 39728c2ecf20Sopenharmony_ci case TOPO_N2N: 39738c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_N; 39748c2ecf20Sopenharmony_ci spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 39758c2ecf20Sopenharmony_ci list_for_each_entry(fcport, &vha->vp_fcports, list) { 39768c2ecf20Sopenharmony_ci fcport->scan_state = QLA_FCPORT_SCAN; 39778c2ecf20Sopenharmony_ci fcport->n2n_flag = 0; 39788c2ecf20Sopenharmony_ci } 39798c2ecf20Sopenharmony_ci id.b24 = 0; 39808c2ecf20Sopenharmony_ci if (wwn_to_u64(vha->port_name) > 39818c2ecf20Sopenharmony_ci wwn_to_u64(rptid_entry->u.f1.port_name)) { 39828c2ecf20Sopenharmony_ci vha->d_id.b24 = 0; 39838c2ecf20Sopenharmony_ci vha->d_id.b.al_pa = 1; 39848c2ecf20Sopenharmony_ci ha->flags.n2n_bigger = 1; 39858c2ecf20Sopenharmony_ci 39868c2ecf20Sopenharmony_ci id.b.al_pa = 2; 39878c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x5075, 39888c2ecf20Sopenharmony_ci "Format 1: assign local id %x remote id %x\n", 39898c2ecf20Sopenharmony_ci vha->d_id.b24, id.b24); 39908c2ecf20Sopenharmony_ci } else { 39918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x5075, 39928c2ecf20Sopenharmony_ci "Format 1: Remote login - Waiting for WWPN %8phC.\n", 39938c2ecf20Sopenharmony_ci rptid_entry->u.f1.port_name); 39948c2ecf20Sopenharmony_ci ha->flags.n2n_bigger = 0; 39958c2ecf20Sopenharmony_ci } 39968c2ecf20Sopenharmony_ci 39978c2ecf20Sopenharmony_ci fcport = qla2x00_find_fcport_by_wwpn(vha, 39988c2ecf20Sopenharmony_ci rptid_entry->u.f1.port_name, 1); 39998c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 40008c2ecf20Sopenharmony_ci 40018c2ecf20Sopenharmony_ci 40028c2ecf20Sopenharmony_ci if (fcport) { 40038c2ecf20Sopenharmony_ci fcport->plogi_nack_done_deadline = jiffies + HZ; 40048c2ecf20Sopenharmony_ci fcport->dm_login_expire = jiffies + 40058c2ecf20Sopenharmony_ci QLA_N2N_WAIT_TIME * HZ; 40068c2ecf20Sopenharmony_ci fcport->scan_state = QLA_FCPORT_FOUND; 40078c2ecf20Sopenharmony_ci fcport->n2n_flag = 1; 40088c2ecf20Sopenharmony_ci fcport->keep_nport_handle = 1; 40098c2ecf20Sopenharmony_ci 40108c2ecf20Sopenharmony_ci if (wwn_to_u64(vha->port_name) > 40118c2ecf20Sopenharmony_ci wwn_to_u64(fcport->port_name)) { 40128c2ecf20Sopenharmony_ci fcport->d_id = id; 40138c2ecf20Sopenharmony_ci } 40148c2ecf20Sopenharmony_ci 40158c2ecf20Sopenharmony_ci switch (fcport->disc_state) { 40168c2ecf20Sopenharmony_ci case DSC_DELETED: 40178c2ecf20Sopenharmony_ci set_bit(RELOGIN_NEEDED, 40188c2ecf20Sopenharmony_ci &vha->dpc_flags); 40198c2ecf20Sopenharmony_ci break; 40208c2ecf20Sopenharmony_ci case DSC_DELETE_PEND: 40218c2ecf20Sopenharmony_ci break; 40228c2ecf20Sopenharmony_ci default: 40238c2ecf20Sopenharmony_ci qlt_schedule_sess_for_deletion(fcport); 40248c2ecf20Sopenharmony_ci break; 40258c2ecf20Sopenharmony_ci } 40268c2ecf20Sopenharmony_ci } else { 40278c2ecf20Sopenharmony_ci qla24xx_post_newsess_work(vha, &id, 40288c2ecf20Sopenharmony_ci rptid_entry->u.f1.port_name, 40298c2ecf20Sopenharmony_ci rptid_entry->u.f1.node_name, 40308c2ecf20Sopenharmony_ci NULL, 40318c2ecf20Sopenharmony_ci FS_FCP_IS_N2N); 40328c2ecf20Sopenharmony_ci } 40338c2ecf20Sopenharmony_ci 40348c2ecf20Sopenharmony_ci /* if our portname is higher then initiate N2N login */ 40358c2ecf20Sopenharmony_ci 40368c2ecf20Sopenharmony_ci set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); 40378c2ecf20Sopenharmony_ci return; 40388c2ecf20Sopenharmony_ci break; 40398c2ecf20Sopenharmony_ci case TOPO_FL: 40408c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_FL; 40418c2ecf20Sopenharmony_ci break; 40428c2ecf20Sopenharmony_ci case TOPO_F: 40438c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_F; 40448c2ecf20Sopenharmony_ci break; 40458c2ecf20Sopenharmony_ci default: 40468c2ecf20Sopenharmony_ci break; 40478c2ecf20Sopenharmony_ci } 40488c2ecf20Sopenharmony_ci 40498c2ecf20Sopenharmony_ci ha->flags.gpsc_supported = 1; 40508c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_F; 40518c2ecf20Sopenharmony_ci /* buffer to buffer credit flag */ 40528c2ecf20Sopenharmony_ci vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0; 40538c2ecf20Sopenharmony_ci 40548c2ecf20Sopenharmony_ci if (rptid_entry->vp_idx == 0) { 40558c2ecf20Sopenharmony_ci if (rptid_entry->vp_status == VP_STAT_COMPL) { 40568c2ecf20Sopenharmony_ci /* FA-WWN is only for physical port */ 40578c2ecf20Sopenharmony_ci if (qla_ini_mode_enabled(vha) && 40588c2ecf20Sopenharmony_ci ha->flags.fawwpn_enabled && 40598c2ecf20Sopenharmony_ci (rptid_entry->u.f1.flags & 40608c2ecf20Sopenharmony_ci BIT_6)) { 40618c2ecf20Sopenharmony_ci memcpy(vha->port_name, 40628c2ecf20Sopenharmony_ci rptid_entry->u.f1.port_name, 40638c2ecf20Sopenharmony_ci WWN_SIZE); 40648c2ecf20Sopenharmony_ci } 40658c2ecf20Sopenharmony_ci 40668c2ecf20Sopenharmony_ci qlt_update_host_map(vha, id); 40678c2ecf20Sopenharmony_ci } 40688c2ecf20Sopenharmony_ci 40698c2ecf20Sopenharmony_ci set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); 40708c2ecf20Sopenharmony_ci set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); 40718c2ecf20Sopenharmony_ci } else { 40728c2ecf20Sopenharmony_ci if (rptid_entry->vp_status != VP_STAT_COMPL && 40738c2ecf20Sopenharmony_ci rptid_entry->vp_status != VP_STAT_ID_CHG) { 40748c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ba, 40758c2ecf20Sopenharmony_ci "Could not acquire ID for VP[%d].\n", 40768c2ecf20Sopenharmony_ci rptid_entry->vp_idx); 40778c2ecf20Sopenharmony_ci return; 40788c2ecf20Sopenharmony_ci } 40798c2ecf20Sopenharmony_ci 40808c2ecf20Sopenharmony_ci found = 0; 40818c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->vport_slock, flags); 40828c2ecf20Sopenharmony_ci list_for_each_entry(vp, &ha->vp_list, list) { 40838c2ecf20Sopenharmony_ci if (rptid_entry->vp_idx == vp->vp_idx) { 40848c2ecf20Sopenharmony_ci found = 1; 40858c2ecf20Sopenharmony_ci break; 40868c2ecf20Sopenharmony_ci } 40878c2ecf20Sopenharmony_ci } 40888c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->vport_slock, flags); 40898c2ecf20Sopenharmony_ci 40908c2ecf20Sopenharmony_ci if (!found) 40918c2ecf20Sopenharmony_ci return; 40928c2ecf20Sopenharmony_ci 40938c2ecf20Sopenharmony_ci qlt_update_host_map(vp, id); 40948c2ecf20Sopenharmony_ci 40958c2ecf20Sopenharmony_ci /* 40968c2ecf20Sopenharmony_ci * Cannot configure here as we are still sitting on the 40978c2ecf20Sopenharmony_ci * response queue. Handle it in dpc context. 40988c2ecf20Sopenharmony_ci */ 40998c2ecf20Sopenharmony_ci set_bit(VP_IDX_ACQUIRED, &vp->vp_flags); 41008c2ecf20Sopenharmony_ci set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags); 41018c2ecf20Sopenharmony_ci set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags); 41028c2ecf20Sopenharmony_ci } 41038c2ecf20Sopenharmony_ci set_bit(VP_DPC_NEEDED, &vha->dpc_flags); 41048c2ecf20Sopenharmony_ci qla2xxx_wake_dpc(vha); 41058c2ecf20Sopenharmony_ci } else if (rptid_entry->format == 2) { 41068c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x505f, 41078c2ecf20Sopenharmony_ci "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n", 41088c2ecf20Sopenharmony_ci rptid_entry->port_id[2], rptid_entry->port_id[1], 41098c2ecf20Sopenharmony_ci rptid_entry->port_id[0]); 41108c2ecf20Sopenharmony_ci 41118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_async, vha, 0x5075, 41128c2ecf20Sopenharmony_ci "N2N: Remote WWPN %8phC.\n", 41138c2ecf20Sopenharmony_ci rptid_entry->u.f2.port_name); 41148c2ecf20Sopenharmony_ci 41158c2ecf20Sopenharmony_ci /* N2N. direct connect */ 41168c2ecf20Sopenharmony_ci ha->current_topology = ISP_CFG_N; 41178c2ecf20Sopenharmony_ci ha->flags.rida_fmt2 = 1; 41188c2ecf20Sopenharmony_ci vha->d_id.b.domain = rptid_entry->port_id[2]; 41198c2ecf20Sopenharmony_ci vha->d_id.b.area = rptid_entry->port_id[1]; 41208c2ecf20Sopenharmony_ci vha->d_id.b.al_pa = rptid_entry->port_id[0]; 41218c2ecf20Sopenharmony_ci 41228c2ecf20Sopenharmony_ci ha->flags.n2n_ae = 1; 41238c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->vport_slock, flags); 41248c2ecf20Sopenharmony_ci qlt_update_vp_map(vha, SET_AL_PA); 41258c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->vport_slock, flags); 41268c2ecf20Sopenharmony_ci 41278c2ecf20Sopenharmony_ci list_for_each_entry(fcport, &vha->vp_fcports, list) { 41288c2ecf20Sopenharmony_ci fcport->scan_state = QLA_FCPORT_SCAN; 41298c2ecf20Sopenharmony_ci fcport->n2n_flag = 0; 41308c2ecf20Sopenharmony_ci } 41318c2ecf20Sopenharmony_ci 41328c2ecf20Sopenharmony_ci fcport = qla2x00_find_fcport_by_wwpn(vha, 41338c2ecf20Sopenharmony_ci rptid_entry->u.f2.port_name, 1); 41348c2ecf20Sopenharmony_ci 41358c2ecf20Sopenharmony_ci if (fcport) { 41368c2ecf20Sopenharmony_ci fcport->login_retry = vha->hw->login_retry_count; 41378c2ecf20Sopenharmony_ci fcport->plogi_nack_done_deadline = jiffies + HZ; 41388c2ecf20Sopenharmony_ci fcport->scan_state = QLA_FCPORT_FOUND; 41398c2ecf20Sopenharmony_ci fcport->keep_nport_handle = 1; 41408c2ecf20Sopenharmony_ci fcport->n2n_flag = 1; 41418c2ecf20Sopenharmony_ci fcport->d_id.b.domain = 41428c2ecf20Sopenharmony_ci rptid_entry->u.f2.remote_nport_id[2]; 41438c2ecf20Sopenharmony_ci fcport->d_id.b.area = 41448c2ecf20Sopenharmony_ci rptid_entry->u.f2.remote_nport_id[1]; 41458c2ecf20Sopenharmony_ci fcport->d_id.b.al_pa = 41468c2ecf20Sopenharmony_ci rptid_entry->u.f2.remote_nport_id[0]; 41478c2ecf20Sopenharmony_ci } 41488c2ecf20Sopenharmony_ci } 41498c2ecf20Sopenharmony_ci} 41508c2ecf20Sopenharmony_ci 41518c2ecf20Sopenharmony_ci/* 41528c2ecf20Sopenharmony_ci * qla24xx_modify_vp_config 41538c2ecf20Sopenharmony_ci * Change VP configuration for vha 41548c2ecf20Sopenharmony_ci * 41558c2ecf20Sopenharmony_ci * Input: 41568c2ecf20Sopenharmony_ci * vha = adapter block pointer. 41578c2ecf20Sopenharmony_ci * 41588c2ecf20Sopenharmony_ci * Returns: 41598c2ecf20Sopenharmony_ci * qla2xxx local function return status code. 41608c2ecf20Sopenharmony_ci * 41618c2ecf20Sopenharmony_ci * Context: 41628c2ecf20Sopenharmony_ci * Kernel context. 41638c2ecf20Sopenharmony_ci */ 41648c2ecf20Sopenharmony_ciint 41658c2ecf20Sopenharmony_ciqla24xx_modify_vp_config(scsi_qla_host_t *vha) 41668c2ecf20Sopenharmony_ci{ 41678c2ecf20Sopenharmony_ci int rval; 41688c2ecf20Sopenharmony_ci struct vp_config_entry_24xx *vpmod; 41698c2ecf20Sopenharmony_ci dma_addr_t vpmod_dma; 41708c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 41718c2ecf20Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 41728c2ecf20Sopenharmony_ci 41738c2ecf20Sopenharmony_ci /* This can be called by the parent */ 41748c2ecf20Sopenharmony_ci 41758c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb, 41768c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 41778c2ecf20Sopenharmony_ci 41788c2ecf20Sopenharmony_ci vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma); 41798c2ecf20Sopenharmony_ci if (!vpmod) { 41808c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x10bc, 41818c2ecf20Sopenharmony_ci "Failed to allocate modify VP IOCB.\n"); 41828c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 41838c2ecf20Sopenharmony_ci } 41848c2ecf20Sopenharmony_ci 41858c2ecf20Sopenharmony_ci vpmod->entry_type = VP_CONFIG_IOCB_TYPE; 41868c2ecf20Sopenharmony_ci vpmod->entry_count = 1; 41878c2ecf20Sopenharmony_ci vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS; 41888c2ecf20Sopenharmony_ci vpmod->vp_count = 1; 41898c2ecf20Sopenharmony_ci vpmod->vp_index1 = vha->vp_idx; 41908c2ecf20Sopenharmony_ci vpmod->options_idx1 = BIT_3|BIT_4|BIT_5; 41918c2ecf20Sopenharmony_ci 41928c2ecf20Sopenharmony_ci qlt_modify_vp_config(vha, vpmod); 41938c2ecf20Sopenharmony_ci 41948c2ecf20Sopenharmony_ci memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE); 41958c2ecf20Sopenharmony_ci memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE); 41968c2ecf20Sopenharmony_ci vpmod->entry_count = 1; 41978c2ecf20Sopenharmony_ci 41988c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0); 41998c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 42008c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10bd, 42018c2ecf20Sopenharmony_ci "Failed to issue VP config IOCB (%x).\n", rval); 42028c2ecf20Sopenharmony_ci } else if (vpmod->comp_status != 0) { 42038c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10be, 42048c2ecf20Sopenharmony_ci "Failed to complete IOCB -- error status (%x).\n", 42058c2ecf20Sopenharmony_ci vpmod->comp_status); 42068c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 42078c2ecf20Sopenharmony_ci } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) { 42088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10bf, 42098c2ecf20Sopenharmony_ci "Failed to complete IOCB -- completion status (%x).\n", 42108c2ecf20Sopenharmony_ci le16_to_cpu(vpmod->comp_status)); 42118c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 42128c2ecf20Sopenharmony_ci } else { 42138c2ecf20Sopenharmony_ci /* EMPTY */ 42148c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0, 42158c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 42168c2ecf20Sopenharmony_ci fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING); 42178c2ecf20Sopenharmony_ci } 42188c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma); 42198c2ecf20Sopenharmony_ci 42208c2ecf20Sopenharmony_ci return rval; 42218c2ecf20Sopenharmony_ci} 42228c2ecf20Sopenharmony_ci 42238c2ecf20Sopenharmony_ci/* 42248c2ecf20Sopenharmony_ci * qla2x00_send_change_request 42258c2ecf20Sopenharmony_ci * Receive or disable RSCN request from fabric controller 42268c2ecf20Sopenharmony_ci * 42278c2ecf20Sopenharmony_ci * Input: 42288c2ecf20Sopenharmony_ci * ha = adapter block pointer 42298c2ecf20Sopenharmony_ci * format = registration format: 42308c2ecf20Sopenharmony_ci * 0 - Reserved 42318c2ecf20Sopenharmony_ci * 1 - Fabric detected registration 42328c2ecf20Sopenharmony_ci * 2 - N_port detected registration 42338c2ecf20Sopenharmony_ci * 3 - Full registration 42348c2ecf20Sopenharmony_ci * FF - clear registration 42358c2ecf20Sopenharmony_ci * vp_idx = Virtual port index 42368c2ecf20Sopenharmony_ci * 42378c2ecf20Sopenharmony_ci * Returns: 42388c2ecf20Sopenharmony_ci * qla2x00 local function return status code. 42398c2ecf20Sopenharmony_ci * 42408c2ecf20Sopenharmony_ci * Context: 42418c2ecf20Sopenharmony_ci * Kernel Context 42428c2ecf20Sopenharmony_ci */ 42438c2ecf20Sopenharmony_ci 42448c2ecf20Sopenharmony_ciint 42458c2ecf20Sopenharmony_ciqla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format, 42468c2ecf20Sopenharmony_ci uint16_t vp_idx) 42478c2ecf20Sopenharmony_ci{ 42488c2ecf20Sopenharmony_ci int rval; 42498c2ecf20Sopenharmony_ci mbx_cmd_t mc; 42508c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 42518c2ecf20Sopenharmony_ci 42528c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7, 42538c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 42548c2ecf20Sopenharmony_ci 42558c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 42568c2ecf20Sopenharmony_ci mcp->mb[1] = format; 42578c2ecf20Sopenharmony_ci mcp->mb[9] = vp_idx; 42588c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_1|MBX_0; 42598c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0|MBX_1; 42608c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 42618c2ecf20Sopenharmony_ci mcp->flags = 0; 42628c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 42638c2ecf20Sopenharmony_ci 42648c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) { 42658c2ecf20Sopenharmony_ci if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 42668c2ecf20Sopenharmony_ci rval = BIT_1; 42678c2ecf20Sopenharmony_ci } 42688c2ecf20Sopenharmony_ci } else 42698c2ecf20Sopenharmony_ci rval = BIT_1; 42708c2ecf20Sopenharmony_ci 42718c2ecf20Sopenharmony_ci return rval; 42728c2ecf20Sopenharmony_ci} 42738c2ecf20Sopenharmony_ci 42748c2ecf20Sopenharmony_ciint 42758c2ecf20Sopenharmony_ciqla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, 42768c2ecf20Sopenharmony_ci uint32_t size) 42778c2ecf20Sopenharmony_ci{ 42788c2ecf20Sopenharmony_ci int rval; 42798c2ecf20Sopenharmony_ci mbx_cmd_t mc; 42808c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 42818c2ecf20Sopenharmony_ci 42828c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009, 42838c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 42848c2ecf20Sopenharmony_ci 42858c2ecf20Sopenharmony_ci if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) { 42868c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; 42878c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(addr); 42888c2ecf20Sopenharmony_ci mcp->mb[10] = 0; 42898c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_8|MBX_0; 42908c2ecf20Sopenharmony_ci } else { 42918c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DUMP_RISC_RAM; 42928c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 42938c2ecf20Sopenharmony_ci } 42948c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(addr); 42958c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(req_dma); 42968c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(req_dma); 42978c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(req_dma)); 42988c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(req_dma)); 42998c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; 43008c2ecf20Sopenharmony_ci if (IS_FWI2_CAPABLE(vha->hw)) { 43018c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(size); 43028c2ecf20Sopenharmony_ci mcp->mb[5] = LSW(size); 43038c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_5|MBX_4; 43048c2ecf20Sopenharmony_ci } else { 43058c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(size); 43068c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_4; 43078c2ecf20Sopenharmony_ci } 43088c2ecf20Sopenharmony_ci 43098c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 43108c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 43118c2ecf20Sopenharmony_ci mcp->flags = 0; 43128c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 43138c2ecf20Sopenharmony_ci 43148c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 43158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1008, 43168c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 43178c2ecf20Sopenharmony_ci } else { 43188c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007, 43198c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 43208c2ecf20Sopenharmony_ci } 43218c2ecf20Sopenharmony_ci 43228c2ecf20Sopenharmony_ci return rval; 43238c2ecf20Sopenharmony_ci} 43248c2ecf20Sopenharmony_ci/* 84XX Support **************************************************************/ 43258c2ecf20Sopenharmony_ci 43268c2ecf20Sopenharmony_cistruct cs84xx_mgmt_cmd { 43278c2ecf20Sopenharmony_ci union { 43288c2ecf20Sopenharmony_ci struct verify_chip_entry_84xx req; 43298c2ecf20Sopenharmony_ci struct verify_chip_rsp_84xx rsp; 43308c2ecf20Sopenharmony_ci } p; 43318c2ecf20Sopenharmony_ci}; 43328c2ecf20Sopenharmony_ci 43338c2ecf20Sopenharmony_ciint 43348c2ecf20Sopenharmony_ciqla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) 43358c2ecf20Sopenharmony_ci{ 43368c2ecf20Sopenharmony_ci int rval, retry; 43378c2ecf20Sopenharmony_ci struct cs84xx_mgmt_cmd *mn; 43388c2ecf20Sopenharmony_ci dma_addr_t mn_dma; 43398c2ecf20Sopenharmony_ci uint16_t options; 43408c2ecf20Sopenharmony_ci unsigned long flags; 43418c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 43428c2ecf20Sopenharmony_ci 43438c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8, 43448c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 43458c2ecf20Sopenharmony_ci 43468c2ecf20Sopenharmony_ci mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); 43478c2ecf20Sopenharmony_ci if (mn == NULL) { 43488c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 43498c2ecf20Sopenharmony_ci } 43508c2ecf20Sopenharmony_ci 43518c2ecf20Sopenharmony_ci /* Force Update? */ 43528c2ecf20Sopenharmony_ci options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; 43538c2ecf20Sopenharmony_ci /* Diagnostic firmware? */ 43548c2ecf20Sopenharmony_ci /* options |= MENLO_DIAG_FW; */ 43558c2ecf20Sopenharmony_ci /* We update the firmware with only one data sequence. */ 43568c2ecf20Sopenharmony_ci options |= VCO_END_OF_DATA; 43578c2ecf20Sopenharmony_ci 43588c2ecf20Sopenharmony_ci do { 43598c2ecf20Sopenharmony_ci retry = 0; 43608c2ecf20Sopenharmony_ci memset(mn, 0, sizeof(*mn)); 43618c2ecf20Sopenharmony_ci mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; 43628c2ecf20Sopenharmony_ci mn->p.req.entry_count = 1; 43638c2ecf20Sopenharmony_ci mn->p.req.options = cpu_to_le16(options); 43648c2ecf20Sopenharmony_ci 43658c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c, 43668c2ecf20Sopenharmony_ci "Dump of Verify Request.\n"); 43678c2ecf20Sopenharmony_ci ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e, 43688c2ecf20Sopenharmony_ci mn, sizeof(*mn)); 43698c2ecf20Sopenharmony_ci 43708c2ecf20Sopenharmony_ci rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); 43718c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 43728c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10cb, 43738c2ecf20Sopenharmony_ci "Failed to issue verify IOCB (%x).\n", rval); 43748c2ecf20Sopenharmony_ci goto verify_done; 43758c2ecf20Sopenharmony_ci } 43768c2ecf20Sopenharmony_ci 43778c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110, 43788c2ecf20Sopenharmony_ci "Dump of Verify Response.\n"); 43798c2ecf20Sopenharmony_ci ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118, 43808c2ecf20Sopenharmony_ci mn, sizeof(*mn)); 43818c2ecf20Sopenharmony_ci 43828c2ecf20Sopenharmony_ci status[0] = le16_to_cpu(mn->p.rsp.comp_status); 43838c2ecf20Sopenharmony_ci status[1] = status[0] == CS_VCS_CHIP_FAILURE ? 43848c2ecf20Sopenharmony_ci le16_to_cpu(mn->p.rsp.failure_code) : 0; 43858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce, 43868c2ecf20Sopenharmony_ci "cs=%x fc=%x.\n", status[0], status[1]); 43878c2ecf20Sopenharmony_ci 43888c2ecf20Sopenharmony_ci if (status[0] != CS_COMPLETE) { 43898c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 43908c2ecf20Sopenharmony_ci if (!(options & VCO_DONT_UPDATE_FW)) { 43918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10cf, 43928c2ecf20Sopenharmony_ci "Firmware update failed. Retrying " 43938c2ecf20Sopenharmony_ci "without update firmware.\n"); 43948c2ecf20Sopenharmony_ci options |= VCO_DONT_UPDATE_FW; 43958c2ecf20Sopenharmony_ci options &= ~VCO_FORCE_UPDATE; 43968c2ecf20Sopenharmony_ci retry = 1; 43978c2ecf20Sopenharmony_ci } 43988c2ecf20Sopenharmony_ci } else { 43998c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0, 44008c2ecf20Sopenharmony_ci "Firmware updated to %x.\n", 44018c2ecf20Sopenharmony_ci le32_to_cpu(mn->p.rsp.fw_ver)); 44028c2ecf20Sopenharmony_ci 44038c2ecf20Sopenharmony_ci /* NOTE: we only update OP firmware. */ 44048c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->cs84xx->access_lock, flags); 44058c2ecf20Sopenharmony_ci ha->cs84xx->op_fw_version = 44068c2ecf20Sopenharmony_ci le32_to_cpu(mn->p.rsp.fw_ver); 44078c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->cs84xx->access_lock, 44088c2ecf20Sopenharmony_ci flags); 44098c2ecf20Sopenharmony_ci } 44108c2ecf20Sopenharmony_ci } while (retry); 44118c2ecf20Sopenharmony_ci 44128c2ecf20Sopenharmony_civerify_done: 44138c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, mn, mn_dma); 44148c2ecf20Sopenharmony_ci 44158c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 44168c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10d1, 44178c2ecf20Sopenharmony_ci "Failed=%x.\n", rval); 44188c2ecf20Sopenharmony_ci } else { 44198c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2, 44208c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 44218c2ecf20Sopenharmony_ci } 44228c2ecf20Sopenharmony_ci 44238c2ecf20Sopenharmony_ci return rval; 44248c2ecf20Sopenharmony_ci} 44258c2ecf20Sopenharmony_ci 44268c2ecf20Sopenharmony_ciint 44278c2ecf20Sopenharmony_ciqla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) 44288c2ecf20Sopenharmony_ci{ 44298c2ecf20Sopenharmony_ci int rval; 44308c2ecf20Sopenharmony_ci unsigned long flags; 44318c2ecf20Sopenharmony_ci mbx_cmd_t mc; 44328c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 44338c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 44348c2ecf20Sopenharmony_ci 44358c2ecf20Sopenharmony_ci if (!ha->flags.fw_started) 44368c2ecf20Sopenharmony_ci return QLA_SUCCESS; 44378c2ecf20Sopenharmony_ci 44388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, 44398c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 44408c2ecf20Sopenharmony_ci 44418c2ecf20Sopenharmony_ci if (IS_SHADOW_REG_CAPABLE(ha)) 44428c2ecf20Sopenharmony_ci req->options |= BIT_13; 44438c2ecf20Sopenharmony_ci 44448c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 44458c2ecf20Sopenharmony_ci mcp->mb[1] = req->options; 44468c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(req->dma)); 44478c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(req->dma)); 44488c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(req->dma)); 44498c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(req->dma)); 44508c2ecf20Sopenharmony_ci mcp->mb[5] = req->length; 44518c2ecf20Sopenharmony_ci if (req->rsp) 44528c2ecf20Sopenharmony_ci mcp->mb[10] = req->rsp->id; 44538c2ecf20Sopenharmony_ci mcp->mb[12] = req->qos; 44548c2ecf20Sopenharmony_ci mcp->mb[11] = req->vp_idx; 44558c2ecf20Sopenharmony_ci mcp->mb[13] = req->rid; 44568c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 44578c2ecf20Sopenharmony_ci mcp->mb[15] = 0; 44588c2ecf20Sopenharmony_ci 44598c2ecf20Sopenharmony_ci mcp->mb[4] = req->id; 44608c2ecf20Sopenharmony_ci /* que in ptr index */ 44618c2ecf20Sopenharmony_ci mcp->mb[8] = 0; 44628c2ecf20Sopenharmony_ci /* que out ptr index */ 44638c2ecf20Sopenharmony_ci mcp->mb[9] = *req->out_ptr = 0; 44648c2ecf20Sopenharmony_ci mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7| 44658c2ecf20Sopenharmony_ci MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 44668c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 44678c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT; 44688c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS * 2; 44698c2ecf20Sopenharmony_ci 44708c2ecf20Sopenharmony_ci if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || 44718c2ecf20Sopenharmony_ci IS_QLA28XX(ha)) 44728c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 44738c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 44748c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_15; 44758c2ecf20Sopenharmony_ci /* debug q create issue in SR-IOV */ 44768c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; 44778c2ecf20Sopenharmony_ci } 44788c2ecf20Sopenharmony_ci 44798c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 44808c2ecf20Sopenharmony_ci if (!(req->options & BIT_0)) { 44818c2ecf20Sopenharmony_ci wrt_reg_dword(req->req_q_in, 0); 44828c2ecf20Sopenharmony_ci if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 44838c2ecf20Sopenharmony_ci wrt_reg_dword(req->req_q_out, 0); 44848c2ecf20Sopenharmony_ci } 44858c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 44868c2ecf20Sopenharmony_ci 44878c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 44888c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 44898c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10d4, 44908c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 44918c2ecf20Sopenharmony_ci } else { 44928c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5, 44938c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 44948c2ecf20Sopenharmony_ci } 44958c2ecf20Sopenharmony_ci 44968c2ecf20Sopenharmony_ci return rval; 44978c2ecf20Sopenharmony_ci} 44988c2ecf20Sopenharmony_ci 44998c2ecf20Sopenharmony_ciint 45008c2ecf20Sopenharmony_ciqla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) 45018c2ecf20Sopenharmony_ci{ 45028c2ecf20Sopenharmony_ci int rval; 45038c2ecf20Sopenharmony_ci unsigned long flags; 45048c2ecf20Sopenharmony_ci mbx_cmd_t mc; 45058c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 45068c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 45078c2ecf20Sopenharmony_ci 45088c2ecf20Sopenharmony_ci if (!ha->flags.fw_started) 45098c2ecf20Sopenharmony_ci return QLA_SUCCESS; 45108c2ecf20Sopenharmony_ci 45118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, 45128c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 45138c2ecf20Sopenharmony_ci 45148c2ecf20Sopenharmony_ci if (IS_SHADOW_REG_CAPABLE(ha)) 45158c2ecf20Sopenharmony_ci rsp->options |= BIT_13; 45168c2ecf20Sopenharmony_ci 45178c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 45188c2ecf20Sopenharmony_ci mcp->mb[1] = rsp->options; 45198c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(rsp->dma)); 45208c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(rsp->dma)); 45218c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(rsp->dma)); 45228c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(rsp->dma)); 45238c2ecf20Sopenharmony_ci mcp->mb[5] = rsp->length; 45248c2ecf20Sopenharmony_ci mcp->mb[14] = rsp->msix->entry; 45258c2ecf20Sopenharmony_ci mcp->mb[13] = rsp->rid; 45268c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 45278c2ecf20Sopenharmony_ci mcp->mb[15] = 0; 45288c2ecf20Sopenharmony_ci 45298c2ecf20Sopenharmony_ci mcp->mb[4] = rsp->id; 45308c2ecf20Sopenharmony_ci /* que in ptr index */ 45318c2ecf20Sopenharmony_ci mcp->mb[8] = *rsp->in_ptr = 0; 45328c2ecf20Sopenharmony_ci /* que out ptr index */ 45338c2ecf20Sopenharmony_ci mcp->mb[9] = 0; 45348c2ecf20Sopenharmony_ci mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7 45358c2ecf20Sopenharmony_ci |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 45368c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 45378c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT; 45388c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS * 2; 45398c2ecf20Sopenharmony_ci 45408c2ecf20Sopenharmony_ci if (IS_QLA81XX(ha)) { 45418c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_12|MBX_11|MBX_10; 45428c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 45438c2ecf20Sopenharmony_ci } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 45448c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; 45458c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 45468c2ecf20Sopenharmony_ci /* debug q create issue in SR-IOV */ 45478c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; 45488c2ecf20Sopenharmony_ci } 45498c2ecf20Sopenharmony_ci 45508c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->hardware_lock, flags); 45518c2ecf20Sopenharmony_ci if (!(rsp->options & BIT_0)) { 45528c2ecf20Sopenharmony_ci wrt_reg_dword(rsp->rsp_q_out, 0); 45538c2ecf20Sopenharmony_ci if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 45548c2ecf20Sopenharmony_ci wrt_reg_dword(rsp->rsp_q_in, 0); 45558c2ecf20Sopenharmony_ci } 45568c2ecf20Sopenharmony_ci 45578c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->hardware_lock, flags); 45588c2ecf20Sopenharmony_ci 45598c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 45608c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 45618c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10d7, 45628c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 45638c2ecf20Sopenharmony_ci } else { 45648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8, 45658c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 45668c2ecf20Sopenharmony_ci } 45678c2ecf20Sopenharmony_ci 45688c2ecf20Sopenharmony_ci return rval; 45698c2ecf20Sopenharmony_ci} 45708c2ecf20Sopenharmony_ci 45718c2ecf20Sopenharmony_ciint 45728c2ecf20Sopenharmony_ciqla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) 45738c2ecf20Sopenharmony_ci{ 45748c2ecf20Sopenharmony_ci int rval; 45758c2ecf20Sopenharmony_ci mbx_cmd_t mc; 45768c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 45778c2ecf20Sopenharmony_ci 45788c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9, 45798c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 45808c2ecf20Sopenharmony_ci 45818c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_IDC_ACK; 45828c2ecf20Sopenharmony_ci memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); 45838c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 45848c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 45858c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 45868c2ecf20Sopenharmony_ci mcp->flags = 0; 45878c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 45888c2ecf20Sopenharmony_ci 45898c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 45908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10da, 45918c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 45928c2ecf20Sopenharmony_ci } else { 45938c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db, 45948c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 45958c2ecf20Sopenharmony_ci } 45968c2ecf20Sopenharmony_ci 45978c2ecf20Sopenharmony_ci return rval; 45988c2ecf20Sopenharmony_ci} 45998c2ecf20Sopenharmony_ci 46008c2ecf20Sopenharmony_ciint 46018c2ecf20Sopenharmony_ciqla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) 46028c2ecf20Sopenharmony_ci{ 46038c2ecf20Sopenharmony_ci int rval; 46048c2ecf20Sopenharmony_ci mbx_cmd_t mc; 46058c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 46068c2ecf20Sopenharmony_ci 46078c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, 46088c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 46098c2ecf20Sopenharmony_ci 46108c2ecf20Sopenharmony_ci if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 46118c2ecf20Sopenharmony_ci !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 46128c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 46138c2ecf20Sopenharmony_ci 46148c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 46158c2ecf20Sopenharmony_ci mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE; 46168c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 46178c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 46188c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 46198c2ecf20Sopenharmony_ci mcp->flags = 0; 46208c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 46218c2ecf20Sopenharmony_ci 46228c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 46238c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10dd, 46248c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 46258c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 46268c2ecf20Sopenharmony_ci } else { 46278c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de, 46288c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 46298c2ecf20Sopenharmony_ci *sector_size = mcp->mb[1]; 46308c2ecf20Sopenharmony_ci } 46318c2ecf20Sopenharmony_ci 46328c2ecf20Sopenharmony_ci return rval; 46338c2ecf20Sopenharmony_ci} 46348c2ecf20Sopenharmony_ci 46358c2ecf20Sopenharmony_ciint 46368c2ecf20Sopenharmony_ciqla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) 46378c2ecf20Sopenharmony_ci{ 46388c2ecf20Sopenharmony_ci int rval; 46398c2ecf20Sopenharmony_ci mbx_cmd_t mc; 46408c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 46418c2ecf20Sopenharmony_ci 46428c2ecf20Sopenharmony_ci if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 46438c2ecf20Sopenharmony_ci !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 46448c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 46458c2ecf20Sopenharmony_ci 46468c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, 46478c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 46488c2ecf20Sopenharmony_ci 46498c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 46508c2ecf20Sopenharmony_ci mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE : 46518c2ecf20Sopenharmony_ci FAC_OPT_CMD_WRITE_PROTECT; 46528c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 46538c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 46548c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 46558c2ecf20Sopenharmony_ci mcp->flags = 0; 46568c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 46578c2ecf20Sopenharmony_ci 46588c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 46598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e0, 46608c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 46618c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 46628c2ecf20Sopenharmony_ci } else { 46638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1, 46648c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 46658c2ecf20Sopenharmony_ci } 46668c2ecf20Sopenharmony_ci 46678c2ecf20Sopenharmony_ci return rval; 46688c2ecf20Sopenharmony_ci} 46698c2ecf20Sopenharmony_ci 46708c2ecf20Sopenharmony_ciint 46718c2ecf20Sopenharmony_ciqla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) 46728c2ecf20Sopenharmony_ci{ 46738c2ecf20Sopenharmony_ci int rval; 46748c2ecf20Sopenharmony_ci mbx_cmd_t mc; 46758c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 46768c2ecf20Sopenharmony_ci 46778c2ecf20Sopenharmony_ci if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 46788c2ecf20Sopenharmony_ci !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 46798c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 46808c2ecf20Sopenharmony_ci 46818c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, 46828c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 46838c2ecf20Sopenharmony_ci 46848c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 46858c2ecf20Sopenharmony_ci mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR; 46868c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(start); 46878c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(start); 46888c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(finish); 46898c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(finish); 46908c2ecf20Sopenharmony_ci mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 46918c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 46928c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 46938c2ecf20Sopenharmony_ci mcp->flags = 0; 46948c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 46958c2ecf20Sopenharmony_ci 46968c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 46978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e3, 46988c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 46998c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 47008c2ecf20Sopenharmony_ci } else { 47018c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, 47028c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 47038c2ecf20Sopenharmony_ci } 47048c2ecf20Sopenharmony_ci 47058c2ecf20Sopenharmony_ci return rval; 47068c2ecf20Sopenharmony_ci} 47078c2ecf20Sopenharmony_ci 47088c2ecf20Sopenharmony_ciint 47098c2ecf20Sopenharmony_ciqla81xx_fac_semaphore_access(scsi_qla_host_t *vha, int lock) 47108c2ecf20Sopenharmony_ci{ 47118c2ecf20Sopenharmony_ci int rval = QLA_SUCCESS; 47128c2ecf20Sopenharmony_ci mbx_cmd_t mc; 47138c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 47148c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 47158c2ecf20Sopenharmony_ci 47168c2ecf20Sopenharmony_ci if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && 47178c2ecf20Sopenharmony_ci !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 47188c2ecf20Sopenharmony_ci return rval; 47198c2ecf20Sopenharmony_ci 47208c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, 47218c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 47228c2ecf20Sopenharmony_ci 47238c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 47248c2ecf20Sopenharmony_ci mcp->mb[1] = (lock ? FAC_OPT_CMD_LOCK_SEMAPHORE : 47258c2ecf20Sopenharmony_ci FAC_OPT_CMD_UNLOCK_SEMAPHORE); 47268c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 47278c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 47288c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 47298c2ecf20Sopenharmony_ci mcp->flags = 0; 47308c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 47318c2ecf20Sopenharmony_ci 47328c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 47338c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e3, 47348c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 47358c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 47368c2ecf20Sopenharmony_ci } else { 47378c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, 47388c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 47398c2ecf20Sopenharmony_ci } 47408c2ecf20Sopenharmony_ci 47418c2ecf20Sopenharmony_ci return rval; 47428c2ecf20Sopenharmony_ci} 47438c2ecf20Sopenharmony_ci 47448c2ecf20Sopenharmony_ciint 47458c2ecf20Sopenharmony_ciqla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) 47468c2ecf20Sopenharmony_ci{ 47478c2ecf20Sopenharmony_ci int rval = 0; 47488c2ecf20Sopenharmony_ci mbx_cmd_t mc; 47498c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 47508c2ecf20Sopenharmony_ci 47518c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5, 47528c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 47538c2ecf20Sopenharmony_ci 47548c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_RESTART_MPI_FW; 47558c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 47568c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0|MBX_1; 47578c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 47588c2ecf20Sopenharmony_ci mcp->flags = 0; 47598c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 47608c2ecf20Sopenharmony_ci 47618c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 47628c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e6, 47638c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 47648c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 47658c2ecf20Sopenharmony_ci } else { 47668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7, 47678c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 47688c2ecf20Sopenharmony_ci } 47698c2ecf20Sopenharmony_ci 47708c2ecf20Sopenharmony_ci return rval; 47718c2ecf20Sopenharmony_ci} 47728c2ecf20Sopenharmony_ci 47738c2ecf20Sopenharmony_ciint 47748c2ecf20Sopenharmony_ciqla82xx_set_driver_version(scsi_qla_host_t *vha, char *version) 47758c2ecf20Sopenharmony_ci{ 47768c2ecf20Sopenharmony_ci int rval; 47778c2ecf20Sopenharmony_ci mbx_cmd_t mc; 47788c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 47798c2ecf20Sopenharmony_ci int i; 47808c2ecf20Sopenharmony_ci int len; 47818c2ecf20Sopenharmony_ci __le16 *str; 47828c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 47838c2ecf20Sopenharmony_ci 47848c2ecf20Sopenharmony_ci if (!IS_P3P_TYPE(ha)) 47858c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 47868c2ecf20Sopenharmony_ci 47878c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b, 47888c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 47898c2ecf20Sopenharmony_ci 47908c2ecf20Sopenharmony_ci str = (__force __le16 *)version; 47918c2ecf20Sopenharmony_ci len = strlen(version); 47928c2ecf20Sopenharmony_ci 47938c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_RNID_PARAMS; 47948c2ecf20Sopenharmony_ci mcp->mb[1] = RNID_TYPE_SET_VERSION << 8; 47958c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 47968c2ecf20Sopenharmony_ci for (i = 4; i < 16 && len; i++, str++, len -= 2) { 47978c2ecf20Sopenharmony_ci mcp->mb[i] = le16_to_cpup(str); 47988c2ecf20Sopenharmony_ci mcp->out_mb |= 1<<i; 47998c2ecf20Sopenharmony_ci } 48008c2ecf20Sopenharmony_ci for (; i < 16; i++) { 48018c2ecf20Sopenharmony_ci mcp->mb[i] = 0; 48028c2ecf20Sopenharmony_ci mcp->out_mb |= 1<<i; 48038c2ecf20Sopenharmony_ci } 48048c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 48058c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 48068c2ecf20Sopenharmony_ci mcp->flags = 0; 48078c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 48088c2ecf20Sopenharmony_ci 48098c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 48108c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x117c, 48118c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 48128c2ecf20Sopenharmony_ci } else { 48138c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d, 48148c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 48158c2ecf20Sopenharmony_ci } 48168c2ecf20Sopenharmony_ci 48178c2ecf20Sopenharmony_ci return rval; 48188c2ecf20Sopenharmony_ci} 48198c2ecf20Sopenharmony_ci 48208c2ecf20Sopenharmony_ciint 48218c2ecf20Sopenharmony_ciqla25xx_set_driver_version(scsi_qla_host_t *vha, char *version) 48228c2ecf20Sopenharmony_ci{ 48238c2ecf20Sopenharmony_ci int rval; 48248c2ecf20Sopenharmony_ci mbx_cmd_t mc; 48258c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 48268c2ecf20Sopenharmony_ci int len; 48278c2ecf20Sopenharmony_ci uint16_t dwlen; 48288c2ecf20Sopenharmony_ci uint8_t *str; 48298c2ecf20Sopenharmony_ci dma_addr_t str_dma; 48308c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 48318c2ecf20Sopenharmony_ci 48328c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) || 48338c2ecf20Sopenharmony_ci IS_P3P_TYPE(ha)) 48348c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 48358c2ecf20Sopenharmony_ci 48368c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e, 48378c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 48388c2ecf20Sopenharmony_ci 48398c2ecf20Sopenharmony_ci str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma); 48408c2ecf20Sopenharmony_ci if (!str) { 48418c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x117f, 48428c2ecf20Sopenharmony_ci "Failed to allocate driver version param.\n"); 48438c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 48448c2ecf20Sopenharmony_ci } 48458c2ecf20Sopenharmony_ci 48468c2ecf20Sopenharmony_ci memcpy(str, "\x7\x3\x11\x0", 4); 48478c2ecf20Sopenharmony_ci dwlen = str[0]; 48488c2ecf20Sopenharmony_ci len = dwlen * 4 - 4; 48498c2ecf20Sopenharmony_ci memset(str + 4, 0, len); 48508c2ecf20Sopenharmony_ci if (len > strlen(version)) 48518c2ecf20Sopenharmony_ci len = strlen(version); 48528c2ecf20Sopenharmony_ci memcpy(str + 4, version, len); 48538c2ecf20Sopenharmony_ci 48548c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_RNID_PARAMS; 48558c2ecf20Sopenharmony_ci mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen; 48568c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(str_dma)); 48578c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(str_dma)); 48588c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(str_dma)); 48598c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(str_dma)); 48608c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 48618c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 48628c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 48638c2ecf20Sopenharmony_ci mcp->flags = 0; 48648c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 48658c2ecf20Sopenharmony_ci 48668c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 48678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1180, 48688c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 48698c2ecf20Sopenharmony_ci } else { 48708c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181, 48718c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 48728c2ecf20Sopenharmony_ci } 48738c2ecf20Sopenharmony_ci 48748c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, str, str_dma); 48758c2ecf20Sopenharmony_ci 48768c2ecf20Sopenharmony_ci return rval; 48778c2ecf20Sopenharmony_ci} 48788c2ecf20Sopenharmony_ci 48798c2ecf20Sopenharmony_ciint 48808c2ecf20Sopenharmony_ciqla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, 48818c2ecf20Sopenharmony_ci void *buf, uint16_t bufsiz) 48828c2ecf20Sopenharmony_ci{ 48838c2ecf20Sopenharmony_ci int rval, i; 48848c2ecf20Sopenharmony_ci mbx_cmd_t mc; 48858c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 48868c2ecf20Sopenharmony_ci uint32_t *bp; 48878c2ecf20Sopenharmony_ci 48888c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 48898c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 48908c2ecf20Sopenharmony_ci 48918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159, 48928c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 48938c2ecf20Sopenharmony_ci 48948c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_RNID_PARAMS; 48958c2ecf20Sopenharmony_ci mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8; 48968c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(buf_dma); 48978c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(buf_dma); 48988c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(buf_dma)); 48998c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(buf_dma)); 49008c2ecf20Sopenharmony_ci mcp->mb[8] = bufsiz/4; 49018c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 49028c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 49038c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 49048c2ecf20Sopenharmony_ci mcp->flags = 0; 49058c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 49068c2ecf20Sopenharmony_ci 49078c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 49088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x115a, 49098c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 49108c2ecf20Sopenharmony_ci } else { 49118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b, 49128c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 49138c2ecf20Sopenharmony_ci bp = (uint32_t *) buf; 49148c2ecf20Sopenharmony_ci for (i = 0; i < (bufsiz-4)/4; i++, bp++) 49158c2ecf20Sopenharmony_ci *bp = le32_to_cpu((__force __le32)*bp); 49168c2ecf20Sopenharmony_ci } 49178c2ecf20Sopenharmony_ci 49188c2ecf20Sopenharmony_ci return rval; 49198c2ecf20Sopenharmony_ci} 49208c2ecf20Sopenharmony_ci 49218c2ecf20Sopenharmony_ci#define PUREX_CMD_COUNT 2 49228c2ecf20Sopenharmony_ciint 49238c2ecf20Sopenharmony_ciqla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) 49248c2ecf20Sopenharmony_ci{ 49258c2ecf20Sopenharmony_ci int rval; 49268c2ecf20Sopenharmony_ci mbx_cmd_t mc; 49278c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 49288c2ecf20Sopenharmony_ci uint8_t *els_cmd_map; 49298c2ecf20Sopenharmony_ci dma_addr_t els_cmd_map_dma; 49308c2ecf20Sopenharmony_ci uint8_t cmd_opcode[PUREX_CMD_COUNT]; 49318c2ecf20Sopenharmony_ci uint8_t i, index, purex_bit; 49328c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 49338c2ecf20Sopenharmony_ci 49348c2ecf20Sopenharmony_ci if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && 49358c2ecf20Sopenharmony_ci !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 49368c2ecf20Sopenharmony_ci return QLA_SUCCESS; 49378c2ecf20Sopenharmony_ci 49388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197, 49398c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 49408c2ecf20Sopenharmony_ci 49418c2ecf20Sopenharmony_ci els_cmd_map = dma_alloc_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE, 49428c2ecf20Sopenharmony_ci &els_cmd_map_dma, GFP_KERNEL); 49438c2ecf20Sopenharmony_ci if (!els_cmd_map) { 49448c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x7101, 49458c2ecf20Sopenharmony_ci "Failed to allocate RDP els command param.\n"); 49468c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 49478c2ecf20Sopenharmony_ci } 49488c2ecf20Sopenharmony_ci 49498c2ecf20Sopenharmony_ci /* List of Purex ELS */ 49508c2ecf20Sopenharmony_ci cmd_opcode[0] = ELS_FPIN; 49518c2ecf20Sopenharmony_ci cmd_opcode[1] = ELS_RDP; 49528c2ecf20Sopenharmony_ci 49538c2ecf20Sopenharmony_ci for (i = 0; i < PUREX_CMD_COUNT; i++) { 49548c2ecf20Sopenharmony_ci index = cmd_opcode[i] / 8; 49558c2ecf20Sopenharmony_ci purex_bit = cmd_opcode[i] % 8; 49568c2ecf20Sopenharmony_ci els_cmd_map[index] |= 1 << purex_bit; 49578c2ecf20Sopenharmony_ci } 49588c2ecf20Sopenharmony_ci 49598c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_RNID_PARAMS; 49608c2ecf20Sopenharmony_ci mcp->mb[1] = RNID_TYPE_ELS_CMD << 8; 49618c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(els_cmd_map_dma)); 49628c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(els_cmd_map_dma)); 49638c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(els_cmd_map_dma)); 49648c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(els_cmd_map_dma)); 49658c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 49668c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 49678c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 49688c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT; 49698c2ecf20Sopenharmony_ci mcp->buf_size = ELS_CMD_MAP_SIZE; 49708c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 49718c2ecf20Sopenharmony_ci 49728c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 49738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x118d, 49748c2ecf20Sopenharmony_ci "Failed=%x (%x,%x).\n", rval, mcp->mb[0], mcp->mb[1]); 49758c2ecf20Sopenharmony_ci } else { 49768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c, 49778c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 49788c2ecf20Sopenharmony_ci } 49798c2ecf20Sopenharmony_ci 49808c2ecf20Sopenharmony_ci dma_free_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE, 49818c2ecf20Sopenharmony_ci els_cmd_map, els_cmd_map_dma); 49828c2ecf20Sopenharmony_ci 49838c2ecf20Sopenharmony_ci return rval; 49848c2ecf20Sopenharmony_ci} 49858c2ecf20Sopenharmony_ci 49868c2ecf20Sopenharmony_cistatic int 49878c2ecf20Sopenharmony_ciqla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) 49888c2ecf20Sopenharmony_ci{ 49898c2ecf20Sopenharmony_ci int rval; 49908c2ecf20Sopenharmony_ci mbx_cmd_t mc; 49918c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 49928c2ecf20Sopenharmony_ci 49938c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 49948c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 49958c2ecf20Sopenharmony_ci 49968c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159, 49978c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 49988c2ecf20Sopenharmony_ci 49998c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_RNID_PARAMS; 50008c2ecf20Sopenharmony_ci mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8; 50018c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 50028c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 50038c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 50048c2ecf20Sopenharmony_ci mcp->flags = 0; 50058c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 50068c2ecf20Sopenharmony_ci *temp = mcp->mb[1]; 50078c2ecf20Sopenharmony_ci 50088c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 50098c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x115a, 50108c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 50118c2ecf20Sopenharmony_ci } else { 50128c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b, 50138c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 50148c2ecf20Sopenharmony_ci } 50158c2ecf20Sopenharmony_ci 50168c2ecf20Sopenharmony_ci return rval; 50178c2ecf20Sopenharmony_ci} 50188c2ecf20Sopenharmony_ci 50198c2ecf20Sopenharmony_ciint 50208c2ecf20Sopenharmony_ciqla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, 50218c2ecf20Sopenharmony_ci uint16_t dev, uint16_t off, uint16_t len, uint16_t opt) 50228c2ecf20Sopenharmony_ci{ 50238c2ecf20Sopenharmony_ci int rval; 50248c2ecf20Sopenharmony_ci mbx_cmd_t mc; 50258c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 50268c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 50278c2ecf20Sopenharmony_ci 50288c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 50298c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 50308c2ecf20Sopenharmony_ci 50318c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 50328c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 50338c2ecf20Sopenharmony_ci 50348c2ecf20Sopenharmony_ci if (len == 1) 50358c2ecf20Sopenharmony_ci opt |= BIT_0; 50368c2ecf20Sopenharmony_ci 50378c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_READ_SFP; 50388c2ecf20Sopenharmony_ci mcp->mb[1] = dev; 50398c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(sfp_dma)); 50408c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(sfp_dma)); 50418c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(sfp_dma)); 50428c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(sfp_dma)); 50438c2ecf20Sopenharmony_ci mcp->mb[8] = len; 50448c2ecf20Sopenharmony_ci mcp->mb[9] = off; 50458c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 50468c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 50478c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 50488c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 50498c2ecf20Sopenharmony_ci mcp->flags = 0; 50508c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 50518c2ecf20Sopenharmony_ci 50528c2ecf20Sopenharmony_ci if (opt & BIT_0) 50538c2ecf20Sopenharmony_ci *sfp = mcp->mb[1]; 50548c2ecf20Sopenharmony_ci 50558c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 50568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e9, 50578c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 50588c2ecf20Sopenharmony_ci if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) { 50598c2ecf20Sopenharmony_ci /* sfp is not there */ 50608c2ecf20Sopenharmony_ci rval = QLA_INTERFACE_ERROR; 50618c2ecf20Sopenharmony_ci } 50628c2ecf20Sopenharmony_ci } else { 50638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 50648c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 50658c2ecf20Sopenharmony_ci } 50668c2ecf20Sopenharmony_ci 50678c2ecf20Sopenharmony_ci return rval; 50688c2ecf20Sopenharmony_ci} 50698c2ecf20Sopenharmony_ci 50708c2ecf20Sopenharmony_ciint 50718c2ecf20Sopenharmony_ciqla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, 50728c2ecf20Sopenharmony_ci uint16_t dev, uint16_t off, uint16_t len, uint16_t opt) 50738c2ecf20Sopenharmony_ci{ 50748c2ecf20Sopenharmony_ci int rval; 50758c2ecf20Sopenharmony_ci mbx_cmd_t mc; 50768c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 50778c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 50788c2ecf20Sopenharmony_ci 50798c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb, 50808c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 50818c2ecf20Sopenharmony_ci 50828c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 50838c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 50848c2ecf20Sopenharmony_ci 50858c2ecf20Sopenharmony_ci if (len == 1) 50868c2ecf20Sopenharmony_ci opt |= BIT_0; 50878c2ecf20Sopenharmony_ci 50888c2ecf20Sopenharmony_ci if (opt & BIT_0) 50898c2ecf20Sopenharmony_ci len = *sfp; 50908c2ecf20Sopenharmony_ci 50918c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_WRITE_SFP; 50928c2ecf20Sopenharmony_ci mcp->mb[1] = dev; 50938c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(sfp_dma)); 50948c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(sfp_dma)); 50958c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(sfp_dma)); 50968c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(sfp_dma)); 50978c2ecf20Sopenharmony_ci mcp->mb[8] = len; 50988c2ecf20Sopenharmony_ci mcp->mb[9] = off; 50998c2ecf20Sopenharmony_ci mcp->mb[10] = opt; 51008c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 51018c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 51028c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 51038c2ecf20Sopenharmony_ci mcp->flags = 0; 51048c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 51058c2ecf20Sopenharmony_ci 51068c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 51078c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ec, 51088c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 51098c2ecf20Sopenharmony_ci } else { 51108c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed, 51118c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 51128c2ecf20Sopenharmony_ci } 51138c2ecf20Sopenharmony_ci 51148c2ecf20Sopenharmony_ci return rval; 51158c2ecf20Sopenharmony_ci} 51168c2ecf20Sopenharmony_ci 51178c2ecf20Sopenharmony_ciint 51188c2ecf20Sopenharmony_ciqla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, 51198c2ecf20Sopenharmony_ci uint16_t size_in_bytes, uint16_t *actual_size) 51208c2ecf20Sopenharmony_ci{ 51218c2ecf20Sopenharmony_ci int rval; 51228c2ecf20Sopenharmony_ci mbx_cmd_t mc; 51238c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 51248c2ecf20Sopenharmony_ci 51258c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee, 51268c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 51278c2ecf20Sopenharmony_ci 51288c2ecf20Sopenharmony_ci if (!IS_CNA_CAPABLE(vha->hw)) 51298c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 51308c2ecf20Sopenharmony_ci 51318c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_XGMAC_STATS; 51328c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(stats_dma); 51338c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(stats_dma); 51348c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(stats_dma)); 51358c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(stats_dma)); 51368c2ecf20Sopenharmony_ci mcp->mb[8] = size_in_bytes >> 2; 51378c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 51388c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 51398c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 51408c2ecf20Sopenharmony_ci mcp->flags = 0; 51418c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 51428c2ecf20Sopenharmony_ci 51438c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 51448c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10ef, 51458c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 51468c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 51478c2ecf20Sopenharmony_ci } else { 51488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0, 51498c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 51508c2ecf20Sopenharmony_ci 51518c2ecf20Sopenharmony_ci 51528c2ecf20Sopenharmony_ci *actual_size = mcp->mb[2] << 2; 51538c2ecf20Sopenharmony_ci } 51548c2ecf20Sopenharmony_ci 51558c2ecf20Sopenharmony_ci return rval; 51568c2ecf20Sopenharmony_ci} 51578c2ecf20Sopenharmony_ci 51588c2ecf20Sopenharmony_ciint 51598c2ecf20Sopenharmony_ciqla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, 51608c2ecf20Sopenharmony_ci uint16_t size) 51618c2ecf20Sopenharmony_ci{ 51628c2ecf20Sopenharmony_ci int rval; 51638c2ecf20Sopenharmony_ci mbx_cmd_t mc; 51648c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 51658c2ecf20Sopenharmony_ci 51668c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1, 51678c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 51688c2ecf20Sopenharmony_ci 51698c2ecf20Sopenharmony_ci if (!IS_CNA_CAPABLE(vha->hw)) 51708c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 51718c2ecf20Sopenharmony_ci 51728c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_DCBX_PARAMS; 51738c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 51748c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(tlv_dma); 51758c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(tlv_dma); 51768c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(tlv_dma)); 51778c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(tlv_dma)); 51788c2ecf20Sopenharmony_ci mcp->mb[8] = size; 51798c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 51808c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 51818c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 51828c2ecf20Sopenharmony_ci mcp->flags = 0; 51838c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 51848c2ecf20Sopenharmony_ci 51858c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 51868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10f2, 51878c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 51888c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 51898c2ecf20Sopenharmony_ci } else { 51908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3, 51918c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 51928c2ecf20Sopenharmony_ci } 51938c2ecf20Sopenharmony_ci 51948c2ecf20Sopenharmony_ci return rval; 51958c2ecf20Sopenharmony_ci} 51968c2ecf20Sopenharmony_ci 51978c2ecf20Sopenharmony_ciint 51988c2ecf20Sopenharmony_ciqla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) 51998c2ecf20Sopenharmony_ci{ 52008c2ecf20Sopenharmony_ci int rval; 52018c2ecf20Sopenharmony_ci mbx_cmd_t mc; 52028c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 52038c2ecf20Sopenharmony_ci 52048c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4, 52058c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 52068c2ecf20Sopenharmony_ci 52078c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 52088c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 52098c2ecf20Sopenharmony_ci 52108c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_READ_RAM_EXTENDED; 52118c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(risc_addr); 52128c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(risc_addr); 52138c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_1|MBX_0; 52148c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_0; 52158c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 52168c2ecf20Sopenharmony_ci mcp->flags = 0; 52178c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 52188c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 52198c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10f5, 52208c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 52218c2ecf20Sopenharmony_ci } else { 52228c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6, 52238c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 52248c2ecf20Sopenharmony_ci *data = mcp->mb[3] << 16 | mcp->mb[2]; 52258c2ecf20Sopenharmony_ci } 52268c2ecf20Sopenharmony_ci 52278c2ecf20Sopenharmony_ci return rval; 52288c2ecf20Sopenharmony_ci} 52298c2ecf20Sopenharmony_ci 52308c2ecf20Sopenharmony_ciint 52318c2ecf20Sopenharmony_ciqla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, 52328c2ecf20Sopenharmony_ci uint16_t *mresp) 52338c2ecf20Sopenharmony_ci{ 52348c2ecf20Sopenharmony_ci int rval; 52358c2ecf20Sopenharmony_ci mbx_cmd_t mc; 52368c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 52378c2ecf20Sopenharmony_ci 52388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7, 52398c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 52408c2ecf20Sopenharmony_ci 52418c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 52428c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 52438c2ecf20Sopenharmony_ci mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing 52448c2ecf20Sopenharmony_ci 52458c2ecf20Sopenharmony_ci /* transfer count */ 52468c2ecf20Sopenharmony_ci mcp->mb[10] = LSW(mreq->transfer_size); 52478c2ecf20Sopenharmony_ci mcp->mb[11] = MSW(mreq->transfer_size); 52488c2ecf20Sopenharmony_ci 52498c2ecf20Sopenharmony_ci /* send data address */ 52508c2ecf20Sopenharmony_ci mcp->mb[14] = LSW(mreq->send_dma); 52518c2ecf20Sopenharmony_ci mcp->mb[15] = MSW(mreq->send_dma); 52528c2ecf20Sopenharmony_ci mcp->mb[20] = LSW(MSD(mreq->send_dma)); 52538c2ecf20Sopenharmony_ci mcp->mb[21] = MSW(MSD(mreq->send_dma)); 52548c2ecf20Sopenharmony_ci 52558c2ecf20Sopenharmony_ci /* receive data address */ 52568c2ecf20Sopenharmony_ci mcp->mb[16] = LSW(mreq->rcv_dma); 52578c2ecf20Sopenharmony_ci mcp->mb[17] = MSW(mreq->rcv_dma); 52588c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); 52598c2ecf20Sopenharmony_ci mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); 52608c2ecf20Sopenharmony_ci 52618c2ecf20Sopenharmony_ci /* Iteration count */ 52628c2ecf20Sopenharmony_ci mcp->mb[18] = LSW(mreq->iteration_count); 52638c2ecf20Sopenharmony_ci mcp->mb[19] = MSW(mreq->iteration_count); 52648c2ecf20Sopenharmony_ci 52658c2ecf20Sopenharmony_ci mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 52668c2ecf20Sopenharmony_ci MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 52678c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(vha->hw)) 52688c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_2; 52698c2ecf20Sopenharmony_ci mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 52708c2ecf20Sopenharmony_ci 52718c2ecf20Sopenharmony_ci mcp->buf_size = mreq->transfer_size; 52728c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 52738c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 52748c2ecf20Sopenharmony_ci 52758c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 52768c2ecf20Sopenharmony_ci 52778c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 52788c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10f8, 52798c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x " 52808c2ecf20Sopenharmony_ci "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], 52818c2ecf20Sopenharmony_ci mcp->mb[3], mcp->mb[18], mcp->mb[19]); 52828c2ecf20Sopenharmony_ci } else { 52838c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9, 52848c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 52858c2ecf20Sopenharmony_ci } 52868c2ecf20Sopenharmony_ci 52878c2ecf20Sopenharmony_ci /* Copy mailbox information */ 52888c2ecf20Sopenharmony_ci memcpy( mresp, mcp->mb, 64); 52898c2ecf20Sopenharmony_ci return rval; 52908c2ecf20Sopenharmony_ci} 52918c2ecf20Sopenharmony_ci 52928c2ecf20Sopenharmony_ciint 52938c2ecf20Sopenharmony_ciqla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, 52948c2ecf20Sopenharmony_ci uint16_t *mresp) 52958c2ecf20Sopenharmony_ci{ 52968c2ecf20Sopenharmony_ci int rval; 52978c2ecf20Sopenharmony_ci mbx_cmd_t mc; 52988c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 52998c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 53008c2ecf20Sopenharmony_ci 53018c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa, 53028c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 53038c2ecf20Sopenharmony_ci 53048c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 53058c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; 53068c2ecf20Sopenharmony_ci /* BIT_6 specifies 64bit address */ 53078c2ecf20Sopenharmony_ci mcp->mb[1] = mreq->options | BIT_15 | BIT_6; 53088c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(ha)) { 53098c2ecf20Sopenharmony_ci mcp->mb[2] = vha->fcoe_fcf_idx; 53108c2ecf20Sopenharmony_ci } 53118c2ecf20Sopenharmony_ci mcp->mb[16] = LSW(mreq->rcv_dma); 53128c2ecf20Sopenharmony_ci mcp->mb[17] = MSW(mreq->rcv_dma); 53138c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); 53148c2ecf20Sopenharmony_ci mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); 53158c2ecf20Sopenharmony_ci 53168c2ecf20Sopenharmony_ci mcp->mb[10] = LSW(mreq->transfer_size); 53178c2ecf20Sopenharmony_ci 53188c2ecf20Sopenharmony_ci mcp->mb[14] = LSW(mreq->send_dma); 53198c2ecf20Sopenharmony_ci mcp->mb[15] = MSW(mreq->send_dma); 53208c2ecf20Sopenharmony_ci mcp->mb[20] = LSW(MSD(mreq->send_dma)); 53218c2ecf20Sopenharmony_ci mcp->mb[21] = MSW(MSD(mreq->send_dma)); 53228c2ecf20Sopenharmony_ci 53238c2ecf20Sopenharmony_ci mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| 53248c2ecf20Sopenharmony_ci MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 53258c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(ha)) 53268c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_2; 53278c2ecf20Sopenharmony_ci 53288c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 53298c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || 53308c2ecf20Sopenharmony_ci IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 53318c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_1; 53328c2ecf20Sopenharmony_ci if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || 53338c2ecf20Sopenharmony_ci IS_QLA28XX(ha)) 53348c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_3; 53358c2ecf20Sopenharmony_ci 53368c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 53378c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 53388c2ecf20Sopenharmony_ci mcp->buf_size = mreq->transfer_size; 53398c2ecf20Sopenharmony_ci 53408c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 53418c2ecf20Sopenharmony_ci 53428c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 53438c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10fb, 53448c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 53458c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 53468c2ecf20Sopenharmony_ci } else { 53478c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc, 53488c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 53498c2ecf20Sopenharmony_ci } 53508c2ecf20Sopenharmony_ci 53518c2ecf20Sopenharmony_ci /* Copy mailbox information */ 53528c2ecf20Sopenharmony_ci memcpy(mresp, mcp->mb, 64); 53538c2ecf20Sopenharmony_ci return rval; 53548c2ecf20Sopenharmony_ci} 53558c2ecf20Sopenharmony_ci 53568c2ecf20Sopenharmony_ciint 53578c2ecf20Sopenharmony_ciqla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic) 53588c2ecf20Sopenharmony_ci{ 53598c2ecf20Sopenharmony_ci int rval; 53608c2ecf20Sopenharmony_ci mbx_cmd_t mc; 53618c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 53628c2ecf20Sopenharmony_ci 53638c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd, 53648c2ecf20Sopenharmony_ci "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic); 53658c2ecf20Sopenharmony_ci 53668c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_ISP84XX_RESET; 53678c2ecf20Sopenharmony_ci mcp->mb[1] = enable_diagnostic; 53688c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 53698c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 53708c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 53718c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 53728c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 53738c2ecf20Sopenharmony_ci 53748c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) 53758c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval); 53768c2ecf20Sopenharmony_ci else 53778c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff, 53788c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 53798c2ecf20Sopenharmony_ci 53808c2ecf20Sopenharmony_ci return rval; 53818c2ecf20Sopenharmony_ci} 53828c2ecf20Sopenharmony_ci 53838c2ecf20Sopenharmony_ciint 53848c2ecf20Sopenharmony_ciqla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) 53858c2ecf20Sopenharmony_ci{ 53868c2ecf20Sopenharmony_ci int rval; 53878c2ecf20Sopenharmony_ci mbx_cmd_t mc; 53888c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 53898c2ecf20Sopenharmony_ci 53908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100, 53918c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 53928c2ecf20Sopenharmony_ci 53938c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(vha->hw)) 53948c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 53958c2ecf20Sopenharmony_ci 53968c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED; 53978c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(risc_addr); 53988c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(data); 53998c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(data); 54008c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(risc_addr); 54018c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; 54028c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 54038c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 54048c2ecf20Sopenharmony_ci mcp->flags = 0; 54058c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 54068c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 54078c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1101, 54088c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 54098c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 54108c2ecf20Sopenharmony_ci } else { 54118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, 54128c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 54138c2ecf20Sopenharmony_ci } 54148c2ecf20Sopenharmony_ci 54158c2ecf20Sopenharmony_ci return rval; 54168c2ecf20Sopenharmony_ci} 54178c2ecf20Sopenharmony_ci 54188c2ecf20Sopenharmony_ciint 54198c2ecf20Sopenharmony_ciqla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb) 54208c2ecf20Sopenharmony_ci{ 54218c2ecf20Sopenharmony_ci int rval; 54228c2ecf20Sopenharmony_ci uint32_t stat, timer; 54238c2ecf20Sopenharmony_ci uint16_t mb0 = 0; 54248c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 54258c2ecf20Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 54268c2ecf20Sopenharmony_ci 54278c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 54288c2ecf20Sopenharmony_ci 54298c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103, 54308c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 54318c2ecf20Sopenharmony_ci 54328c2ecf20Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 54338c2ecf20Sopenharmony_ci 54348c2ecf20Sopenharmony_ci /* Write the MBC data to the registers */ 54358c2ecf20Sopenharmony_ci wrt_reg_word(®->mailbox0, MBC_WRITE_MPI_REGISTER); 54368c2ecf20Sopenharmony_ci wrt_reg_word(®->mailbox1, mb[0]); 54378c2ecf20Sopenharmony_ci wrt_reg_word(®->mailbox2, mb[1]); 54388c2ecf20Sopenharmony_ci wrt_reg_word(®->mailbox3, mb[2]); 54398c2ecf20Sopenharmony_ci wrt_reg_word(®->mailbox4, mb[3]); 54408c2ecf20Sopenharmony_ci 54418c2ecf20Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT); 54428c2ecf20Sopenharmony_ci 54438c2ecf20Sopenharmony_ci /* Poll for MBC interrupt */ 54448c2ecf20Sopenharmony_ci for (timer = 6000000; timer; timer--) { 54458c2ecf20Sopenharmony_ci /* Check for pending interrupts. */ 54468c2ecf20Sopenharmony_ci stat = rd_reg_dword(®->host_status); 54478c2ecf20Sopenharmony_ci if (stat & HSRX_RISC_INT) { 54488c2ecf20Sopenharmony_ci stat &= 0xff; 54498c2ecf20Sopenharmony_ci 54508c2ecf20Sopenharmony_ci if (stat == 0x1 || stat == 0x2 || 54518c2ecf20Sopenharmony_ci stat == 0x10 || stat == 0x11) { 54528c2ecf20Sopenharmony_ci set_bit(MBX_INTERRUPT, 54538c2ecf20Sopenharmony_ci &ha->mbx_cmd_flags); 54548c2ecf20Sopenharmony_ci mb0 = rd_reg_word(®->mailbox0); 54558c2ecf20Sopenharmony_ci wrt_reg_dword(®->hccr, 54568c2ecf20Sopenharmony_ci HCCRX_CLR_RISC_INT); 54578c2ecf20Sopenharmony_ci rd_reg_dword(®->hccr); 54588c2ecf20Sopenharmony_ci break; 54598c2ecf20Sopenharmony_ci } 54608c2ecf20Sopenharmony_ci } 54618c2ecf20Sopenharmony_ci udelay(5); 54628c2ecf20Sopenharmony_ci } 54638c2ecf20Sopenharmony_ci 54648c2ecf20Sopenharmony_ci if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) 54658c2ecf20Sopenharmony_ci rval = mb0 & MBS_MASK; 54668c2ecf20Sopenharmony_ci else 54678c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 54688c2ecf20Sopenharmony_ci 54698c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 54708c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1104, 54718c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mb[0]); 54728c2ecf20Sopenharmony_ci } else { 54738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105, 54748c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 54758c2ecf20Sopenharmony_ci } 54768c2ecf20Sopenharmony_ci 54778c2ecf20Sopenharmony_ci return rval; 54788c2ecf20Sopenharmony_ci} 54798c2ecf20Sopenharmony_ci 54808c2ecf20Sopenharmony_ci/* Set the specified data rate */ 54818c2ecf20Sopenharmony_ciint 54828c2ecf20Sopenharmony_ciqla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode) 54838c2ecf20Sopenharmony_ci{ 54848c2ecf20Sopenharmony_ci int rval; 54858c2ecf20Sopenharmony_ci mbx_cmd_t mc; 54868c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 54878c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 54888c2ecf20Sopenharmony_ci uint16_t val; 54898c2ecf20Sopenharmony_ci 54908c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, 54918c2ecf20Sopenharmony_ci "Entered %s speed:0x%x mode:0x%x.\n", __func__, ha->set_data_rate, 54928c2ecf20Sopenharmony_ci mode); 54938c2ecf20Sopenharmony_ci 54948c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 54958c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 54968c2ecf20Sopenharmony_ci 54978c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(*mcp)); 54988c2ecf20Sopenharmony_ci switch (ha->set_data_rate) { 54998c2ecf20Sopenharmony_ci case PORT_SPEED_AUTO: 55008c2ecf20Sopenharmony_ci case PORT_SPEED_4GB: 55018c2ecf20Sopenharmony_ci case PORT_SPEED_8GB: 55028c2ecf20Sopenharmony_ci case PORT_SPEED_16GB: 55038c2ecf20Sopenharmony_ci case PORT_SPEED_32GB: 55048c2ecf20Sopenharmony_ci val = ha->set_data_rate; 55058c2ecf20Sopenharmony_ci break; 55068c2ecf20Sopenharmony_ci default: 55078c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1199, 55088c2ecf20Sopenharmony_ci "Unrecognized speed setting:%d. Setting Autoneg\n", 55098c2ecf20Sopenharmony_ci ha->set_data_rate); 55108c2ecf20Sopenharmony_ci val = ha->set_data_rate = PORT_SPEED_AUTO; 55118c2ecf20Sopenharmony_ci break; 55128c2ecf20Sopenharmony_ci } 55138c2ecf20Sopenharmony_ci 55148c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DATA_RATE; 55158c2ecf20Sopenharmony_ci mcp->mb[1] = mode; 55168c2ecf20Sopenharmony_ci mcp->mb[2] = val; 55178c2ecf20Sopenharmony_ci 55188c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 55198c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 55208c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 55218c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_4|MBX_3; 55228c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 55238c2ecf20Sopenharmony_ci mcp->flags = 0; 55248c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 55258c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 55268c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1107, 55278c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 55288c2ecf20Sopenharmony_ci } else { 55298c2ecf20Sopenharmony_ci if (mcp->mb[1] != 0x7) 55308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1179, 55318c2ecf20Sopenharmony_ci "Speed set:0x%x\n", mcp->mb[1]); 55328c2ecf20Sopenharmony_ci 55338c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, 55348c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 55358c2ecf20Sopenharmony_ci } 55368c2ecf20Sopenharmony_ci 55378c2ecf20Sopenharmony_ci return rval; 55388c2ecf20Sopenharmony_ci} 55398c2ecf20Sopenharmony_ci 55408c2ecf20Sopenharmony_ciint 55418c2ecf20Sopenharmony_ciqla2x00_get_data_rate(scsi_qla_host_t *vha) 55428c2ecf20Sopenharmony_ci{ 55438c2ecf20Sopenharmony_ci int rval; 55448c2ecf20Sopenharmony_ci mbx_cmd_t mc; 55458c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 55468c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 55478c2ecf20Sopenharmony_ci 55488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, 55498c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 55508c2ecf20Sopenharmony_ci 55518c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 55528c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 55538c2ecf20Sopenharmony_ci 55548c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DATA_RATE; 55558c2ecf20Sopenharmony_ci mcp->mb[1] = QLA_GET_DATA_RATE; 55568c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 55578c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 55588c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 55598c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_4|MBX_3; 55608c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 55618c2ecf20Sopenharmony_ci mcp->flags = 0; 55628c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 55638c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 55648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1107, 55658c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 55668c2ecf20Sopenharmony_ci } else { 55678c2ecf20Sopenharmony_ci if (mcp->mb[1] != 0x7) 55688c2ecf20Sopenharmony_ci ha->link_data_rate = mcp->mb[1]; 55698c2ecf20Sopenharmony_ci 55708c2ecf20Sopenharmony_ci if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 55718c2ecf20Sopenharmony_ci if (mcp->mb[4] & BIT_0) 55728c2ecf20Sopenharmony_ci ql_log(ql_log_info, vha, 0x11a2, 55738c2ecf20Sopenharmony_ci "FEC=enabled (data rate).\n"); 55748c2ecf20Sopenharmony_ci } 55758c2ecf20Sopenharmony_ci 55768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, 55778c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 55788c2ecf20Sopenharmony_ci if (mcp->mb[1] != 0x7) 55798c2ecf20Sopenharmony_ci ha->link_data_rate = mcp->mb[1]; 55808c2ecf20Sopenharmony_ci } 55818c2ecf20Sopenharmony_ci 55828c2ecf20Sopenharmony_ci return rval; 55838c2ecf20Sopenharmony_ci} 55848c2ecf20Sopenharmony_ci 55858c2ecf20Sopenharmony_ciint 55868c2ecf20Sopenharmony_ciqla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) 55878c2ecf20Sopenharmony_ci{ 55888c2ecf20Sopenharmony_ci int rval; 55898c2ecf20Sopenharmony_ci mbx_cmd_t mc; 55908c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 55918c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 55928c2ecf20Sopenharmony_ci 55938c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, 55948c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 55958c2ecf20Sopenharmony_ci 55968c2ecf20Sopenharmony_ci if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) && 55978c2ecf20Sopenharmony_ci !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 55988c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 55998c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_PORT_CONFIG; 56008c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 56018c2ecf20Sopenharmony_ci mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 56028c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 56038c2ecf20Sopenharmony_ci mcp->flags = 0; 56048c2ecf20Sopenharmony_ci 56058c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 56068c2ecf20Sopenharmony_ci 56078c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 56088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x110a, 56098c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 56108c2ecf20Sopenharmony_ci } else { 56118c2ecf20Sopenharmony_ci /* Copy all bits to preserve original value */ 56128c2ecf20Sopenharmony_ci memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4); 56138c2ecf20Sopenharmony_ci 56148c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b, 56158c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 56168c2ecf20Sopenharmony_ci } 56178c2ecf20Sopenharmony_ci return rval; 56188c2ecf20Sopenharmony_ci} 56198c2ecf20Sopenharmony_ci 56208c2ecf20Sopenharmony_ciint 56218c2ecf20Sopenharmony_ciqla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb) 56228c2ecf20Sopenharmony_ci{ 56238c2ecf20Sopenharmony_ci int rval; 56248c2ecf20Sopenharmony_ci mbx_cmd_t mc; 56258c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 56268c2ecf20Sopenharmony_ci 56278c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c, 56288c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 56298c2ecf20Sopenharmony_ci 56308c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_PORT_CONFIG; 56318c2ecf20Sopenharmony_ci /* Copy all bits to preserve original setting */ 56328c2ecf20Sopenharmony_ci memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4); 56338c2ecf20Sopenharmony_ci mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 56348c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 56358c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 56368c2ecf20Sopenharmony_ci mcp->flags = 0; 56378c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 56388c2ecf20Sopenharmony_ci 56398c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 56408c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x110d, 56418c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 56428c2ecf20Sopenharmony_ci } else 56438c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e, 56448c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 56458c2ecf20Sopenharmony_ci 56468c2ecf20Sopenharmony_ci return rval; 56478c2ecf20Sopenharmony_ci} 56488c2ecf20Sopenharmony_ci 56498c2ecf20Sopenharmony_ci 56508c2ecf20Sopenharmony_ciint 56518c2ecf20Sopenharmony_ciqla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, 56528c2ecf20Sopenharmony_ci uint16_t *mb) 56538c2ecf20Sopenharmony_ci{ 56548c2ecf20Sopenharmony_ci int rval; 56558c2ecf20Sopenharmony_ci mbx_cmd_t mc; 56568c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 56578c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 56588c2ecf20Sopenharmony_ci 56598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f, 56608c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 56618c2ecf20Sopenharmony_ci 56628c2ecf20Sopenharmony_ci if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) 56638c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 56648c2ecf20Sopenharmony_ci 56658c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_PORT_PARAMS; 56668c2ecf20Sopenharmony_ci mcp->mb[1] = loop_id; 56678c2ecf20Sopenharmony_ci if (ha->flags.fcp_prio_enabled) 56688c2ecf20Sopenharmony_ci mcp->mb[2] = BIT_1; 56698c2ecf20Sopenharmony_ci else 56708c2ecf20Sopenharmony_ci mcp->mb[2] = BIT_2; 56718c2ecf20Sopenharmony_ci mcp->mb[4] = priority & 0xf; 56728c2ecf20Sopenharmony_ci mcp->mb[9] = vha->vp_idx; 56738c2ecf20Sopenharmony_ci mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 56748c2ecf20Sopenharmony_ci mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0; 56758c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 56768c2ecf20Sopenharmony_ci mcp->flags = 0; 56778c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 56788c2ecf20Sopenharmony_ci if (mb != NULL) { 56798c2ecf20Sopenharmony_ci mb[0] = mcp->mb[0]; 56808c2ecf20Sopenharmony_ci mb[1] = mcp->mb[1]; 56818c2ecf20Sopenharmony_ci mb[3] = mcp->mb[3]; 56828c2ecf20Sopenharmony_ci mb[4] = mcp->mb[4]; 56838c2ecf20Sopenharmony_ci } 56848c2ecf20Sopenharmony_ci 56858c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 56868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval); 56878c2ecf20Sopenharmony_ci } else { 56888c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc, 56898c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 56908c2ecf20Sopenharmony_ci } 56918c2ecf20Sopenharmony_ci 56928c2ecf20Sopenharmony_ci return rval; 56938c2ecf20Sopenharmony_ci} 56948c2ecf20Sopenharmony_ci 56958c2ecf20Sopenharmony_ciint 56968c2ecf20Sopenharmony_ciqla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp) 56978c2ecf20Sopenharmony_ci{ 56988c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 56998c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 57008c2ecf20Sopenharmony_ci uint8_t byte; 57018c2ecf20Sopenharmony_ci 57028c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) { 57038c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1150, 57048c2ecf20Sopenharmony_ci "Thermal not supported by this card.\n"); 57058c2ecf20Sopenharmony_ci return rval; 57068c2ecf20Sopenharmony_ci } 57078c2ecf20Sopenharmony_ci 57088c2ecf20Sopenharmony_ci if (IS_QLA25XX(ha)) { 57098c2ecf20Sopenharmony_ci if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && 57108c2ecf20Sopenharmony_ci ha->pdev->subsystem_device == 0x0175) { 57118c2ecf20Sopenharmony_ci rval = qla2x00_read_sfp(vha, 0, &byte, 57128c2ecf20Sopenharmony_ci 0x98, 0x1, 1, BIT_13|BIT_0); 57138c2ecf20Sopenharmony_ci *temp = byte; 57148c2ecf20Sopenharmony_ci return rval; 57158c2ecf20Sopenharmony_ci } 57168c2ecf20Sopenharmony_ci if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && 57178c2ecf20Sopenharmony_ci ha->pdev->subsystem_device == 0x338e) { 57188c2ecf20Sopenharmony_ci rval = qla2x00_read_sfp(vha, 0, &byte, 57198c2ecf20Sopenharmony_ci 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0); 57208c2ecf20Sopenharmony_ci *temp = byte; 57218c2ecf20Sopenharmony_ci return rval; 57228c2ecf20Sopenharmony_ci } 57238c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10c9, 57248c2ecf20Sopenharmony_ci "Thermal not supported by this card.\n"); 57258c2ecf20Sopenharmony_ci return rval; 57268c2ecf20Sopenharmony_ci } 57278c2ecf20Sopenharmony_ci 57288c2ecf20Sopenharmony_ci if (IS_QLA82XX(ha)) { 57298c2ecf20Sopenharmony_ci *temp = qla82xx_read_temperature(vha); 57308c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 57318c2ecf20Sopenharmony_ci return rval; 57328c2ecf20Sopenharmony_ci } else if (IS_QLA8044(ha)) { 57338c2ecf20Sopenharmony_ci *temp = qla8044_read_temperature(vha); 57348c2ecf20Sopenharmony_ci rval = QLA_SUCCESS; 57358c2ecf20Sopenharmony_ci return rval; 57368c2ecf20Sopenharmony_ci } 57378c2ecf20Sopenharmony_ci 57388c2ecf20Sopenharmony_ci rval = qla2x00_read_asic_temperature(vha, temp); 57398c2ecf20Sopenharmony_ci return rval; 57408c2ecf20Sopenharmony_ci} 57418c2ecf20Sopenharmony_ci 57428c2ecf20Sopenharmony_ciint 57438c2ecf20Sopenharmony_ciqla82xx_mbx_intr_enable(scsi_qla_host_t *vha) 57448c2ecf20Sopenharmony_ci{ 57458c2ecf20Sopenharmony_ci int rval; 57468c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 57478c2ecf20Sopenharmony_ci mbx_cmd_t mc; 57488c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 57498c2ecf20Sopenharmony_ci 57508c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017, 57518c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 57528c2ecf20Sopenharmony_ci 57538c2ecf20Sopenharmony_ci if (!IS_FWI2_CAPABLE(ha)) 57548c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 57558c2ecf20Sopenharmony_ci 57568c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(mbx_cmd_t)); 57578c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TOGGLE_INTERRUPT; 57588c2ecf20Sopenharmony_ci mcp->mb[1] = 1; 57598c2ecf20Sopenharmony_ci 57608c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 57618c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 57628c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 57638c2ecf20Sopenharmony_ci mcp->flags = 0; 57648c2ecf20Sopenharmony_ci 57658c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 57668c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 57678c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1016, 57688c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 57698c2ecf20Sopenharmony_ci } else { 57708c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e, 57718c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 57728c2ecf20Sopenharmony_ci } 57738c2ecf20Sopenharmony_ci 57748c2ecf20Sopenharmony_ci return rval; 57758c2ecf20Sopenharmony_ci} 57768c2ecf20Sopenharmony_ci 57778c2ecf20Sopenharmony_ciint 57788c2ecf20Sopenharmony_ciqla82xx_mbx_intr_disable(scsi_qla_host_t *vha) 57798c2ecf20Sopenharmony_ci{ 57808c2ecf20Sopenharmony_ci int rval; 57818c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 57828c2ecf20Sopenharmony_ci mbx_cmd_t mc; 57838c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 57848c2ecf20Sopenharmony_ci 57858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d, 57868c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 57878c2ecf20Sopenharmony_ci 57888c2ecf20Sopenharmony_ci if (!IS_P3P_TYPE(ha)) 57898c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 57908c2ecf20Sopenharmony_ci 57918c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(mbx_cmd_t)); 57928c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_TOGGLE_INTERRUPT; 57938c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 57948c2ecf20Sopenharmony_ci 57958c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 57968c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 57978c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 57988c2ecf20Sopenharmony_ci mcp->flags = 0; 57998c2ecf20Sopenharmony_ci 58008c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 58018c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 58028c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x100c, 58038c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 58048c2ecf20Sopenharmony_ci } else { 58058c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b, 58068c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 58078c2ecf20Sopenharmony_ci } 58088c2ecf20Sopenharmony_ci 58098c2ecf20Sopenharmony_ci return rval; 58108c2ecf20Sopenharmony_ci} 58118c2ecf20Sopenharmony_ci 58128c2ecf20Sopenharmony_ciint 58138c2ecf20Sopenharmony_ciqla82xx_md_get_template_size(scsi_qla_host_t *vha) 58148c2ecf20Sopenharmony_ci{ 58158c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 58168c2ecf20Sopenharmony_ci mbx_cmd_t mc; 58178c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 58188c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 58198c2ecf20Sopenharmony_ci 58208c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f, 58218c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 58228c2ecf20Sopenharmony_ci 58238c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 58248c2ecf20Sopenharmony_ci mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 58258c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 58268c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(RQST_TMPLT_SIZE); 58278c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(RQST_TMPLT_SIZE); 58288c2ecf20Sopenharmony_ci 58298c2ecf20Sopenharmony_ci mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 58308c2ecf20Sopenharmony_ci mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8| 58318c2ecf20Sopenharmony_ci MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 58328c2ecf20Sopenharmony_ci 58338c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 58348c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 58358c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 58368c2ecf20Sopenharmony_ci 58378c2ecf20Sopenharmony_ci /* Always copy back return mailbox values. */ 58388c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 58398c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1120, 58408c2ecf20Sopenharmony_ci "mailbox command FAILED=0x%x, subcode=%x.\n", 58418c2ecf20Sopenharmony_ci (mcp->mb[1] << 16) | mcp->mb[0], 58428c2ecf20Sopenharmony_ci (mcp->mb[3] << 16) | mcp->mb[2]); 58438c2ecf20Sopenharmony_ci } else { 58448c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121, 58458c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 58468c2ecf20Sopenharmony_ci ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]); 58478c2ecf20Sopenharmony_ci if (!ha->md_template_size) { 58488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1122, 58498c2ecf20Sopenharmony_ci "Null template size obtained.\n"); 58508c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 58518c2ecf20Sopenharmony_ci } 58528c2ecf20Sopenharmony_ci } 58538c2ecf20Sopenharmony_ci return rval; 58548c2ecf20Sopenharmony_ci} 58558c2ecf20Sopenharmony_ci 58568c2ecf20Sopenharmony_ciint 58578c2ecf20Sopenharmony_ciqla82xx_md_get_template(scsi_qla_host_t *vha) 58588c2ecf20Sopenharmony_ci{ 58598c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 58608c2ecf20Sopenharmony_ci mbx_cmd_t mc; 58618c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 58628c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 58638c2ecf20Sopenharmony_ci 58648c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123, 58658c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 58668c2ecf20Sopenharmony_ci 58678c2ecf20Sopenharmony_ci ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, 58688c2ecf20Sopenharmony_ci ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); 58698c2ecf20Sopenharmony_ci if (!ha->md_tmplt_hdr) { 58708c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1124, 58718c2ecf20Sopenharmony_ci "Unable to allocate memory for Minidump template.\n"); 58728c2ecf20Sopenharmony_ci return rval; 58738c2ecf20Sopenharmony_ci } 58748c2ecf20Sopenharmony_ci 58758c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 58768c2ecf20Sopenharmony_ci mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 58778c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 58788c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(RQST_TMPLT); 58798c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(RQST_TMPLT); 58808c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma)); 58818c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma)); 58828c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma)); 58838c2ecf20Sopenharmony_ci mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma)); 58848c2ecf20Sopenharmony_ci mcp->mb[8] = LSW(ha->md_template_size); 58858c2ecf20Sopenharmony_ci mcp->mb[9] = MSW(ha->md_template_size); 58868c2ecf20Sopenharmony_ci 58878c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 58888c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 58898c2ecf20Sopenharmony_ci mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8| 58908c2ecf20Sopenharmony_ci MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 58918c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 58928c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 58938c2ecf20Sopenharmony_ci 58948c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 58958c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1125, 58968c2ecf20Sopenharmony_ci "mailbox command FAILED=0x%x, subcode=%x.\n", 58978c2ecf20Sopenharmony_ci ((mcp->mb[1] << 16) | mcp->mb[0]), 58988c2ecf20Sopenharmony_ci ((mcp->mb[3] << 16) | mcp->mb[2])); 58998c2ecf20Sopenharmony_ci } else 59008c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126, 59018c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 59028c2ecf20Sopenharmony_ci return rval; 59038c2ecf20Sopenharmony_ci} 59048c2ecf20Sopenharmony_ci 59058c2ecf20Sopenharmony_ciint 59068c2ecf20Sopenharmony_ciqla8044_md_get_template(scsi_qla_host_t *vha) 59078c2ecf20Sopenharmony_ci{ 59088c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 59098c2ecf20Sopenharmony_ci mbx_cmd_t mc; 59108c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 59118c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 59128c2ecf20Sopenharmony_ci int offset = 0, size = MINIDUMP_SIZE_36K; 59138c2ecf20Sopenharmony_ci 59148c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f, 59158c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 59168c2ecf20Sopenharmony_ci 59178c2ecf20Sopenharmony_ci ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, 59188c2ecf20Sopenharmony_ci ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); 59198c2ecf20Sopenharmony_ci if (!ha->md_tmplt_hdr) { 59208c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xb11b, 59218c2ecf20Sopenharmony_ci "Unable to allocate memory for Minidump template.\n"); 59228c2ecf20Sopenharmony_ci return rval; 59238c2ecf20Sopenharmony_ci } 59248c2ecf20Sopenharmony_ci 59258c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 59268c2ecf20Sopenharmony_ci while (offset < ha->md_template_size) { 59278c2ecf20Sopenharmony_ci mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 59288c2ecf20Sopenharmony_ci mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 59298c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(RQST_TMPLT); 59308c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(RQST_TMPLT); 59318c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset)); 59328c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset)); 59338c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset)); 59348c2ecf20Sopenharmony_ci mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset)); 59358c2ecf20Sopenharmony_ci mcp->mb[8] = LSW(size); 59368c2ecf20Sopenharmony_ci mcp->mb[9] = MSW(size); 59378c2ecf20Sopenharmony_ci mcp->mb[10] = offset & 0x0000FFFF; 59388c2ecf20Sopenharmony_ci mcp->mb[11] = offset & 0xFFFF0000; 59398c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 59408c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 59418c2ecf20Sopenharmony_ci mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8| 59428c2ecf20Sopenharmony_ci MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 59438c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 59448c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 59458c2ecf20Sopenharmony_ci 59468c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 59478c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0xb11c, 59488c2ecf20Sopenharmony_ci "mailbox command FAILED=0x%x, subcode=%x.\n", 59498c2ecf20Sopenharmony_ci ((mcp->mb[1] << 16) | mcp->mb[0]), 59508c2ecf20Sopenharmony_ci ((mcp->mb[3] << 16) | mcp->mb[2])); 59518c2ecf20Sopenharmony_ci return rval; 59528c2ecf20Sopenharmony_ci } else 59538c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d, 59548c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 59558c2ecf20Sopenharmony_ci offset = offset + size; 59568c2ecf20Sopenharmony_ci } 59578c2ecf20Sopenharmony_ci return rval; 59588c2ecf20Sopenharmony_ci} 59598c2ecf20Sopenharmony_ci 59608c2ecf20Sopenharmony_ciint 59618c2ecf20Sopenharmony_ciqla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) 59628c2ecf20Sopenharmony_ci{ 59638c2ecf20Sopenharmony_ci int rval; 59648c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 59658c2ecf20Sopenharmony_ci mbx_cmd_t mc; 59668c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 59678c2ecf20Sopenharmony_ci 59688c2ecf20Sopenharmony_ci if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 59698c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 59708c2ecf20Sopenharmony_ci 59718c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133, 59728c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 59738c2ecf20Sopenharmony_ci 59748c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(mbx_cmd_t)); 59758c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_LED_CONFIG; 59768c2ecf20Sopenharmony_ci mcp->mb[1] = led_cfg[0]; 59778c2ecf20Sopenharmony_ci mcp->mb[2] = led_cfg[1]; 59788c2ecf20Sopenharmony_ci if (IS_QLA8031(ha)) { 59798c2ecf20Sopenharmony_ci mcp->mb[3] = led_cfg[2]; 59808c2ecf20Sopenharmony_ci mcp->mb[4] = led_cfg[3]; 59818c2ecf20Sopenharmony_ci mcp->mb[5] = led_cfg[4]; 59828c2ecf20Sopenharmony_ci mcp->mb[6] = led_cfg[5]; 59838c2ecf20Sopenharmony_ci } 59848c2ecf20Sopenharmony_ci 59858c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 59868c2ecf20Sopenharmony_ci if (IS_QLA8031(ha)) 59878c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3; 59888c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 59898c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 59908c2ecf20Sopenharmony_ci mcp->flags = 0; 59918c2ecf20Sopenharmony_ci 59928c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 59938c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 59948c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1134, 59958c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 59968c2ecf20Sopenharmony_ci } else { 59978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135, 59988c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 59998c2ecf20Sopenharmony_ci } 60008c2ecf20Sopenharmony_ci 60018c2ecf20Sopenharmony_ci return rval; 60028c2ecf20Sopenharmony_ci} 60038c2ecf20Sopenharmony_ci 60048c2ecf20Sopenharmony_ciint 60058c2ecf20Sopenharmony_ciqla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) 60068c2ecf20Sopenharmony_ci{ 60078c2ecf20Sopenharmony_ci int rval; 60088c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 60098c2ecf20Sopenharmony_ci mbx_cmd_t mc; 60108c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 60118c2ecf20Sopenharmony_ci 60128c2ecf20Sopenharmony_ci if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 60138c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 60148c2ecf20Sopenharmony_ci 60158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136, 60168c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 60178c2ecf20Sopenharmony_ci 60188c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(mbx_cmd_t)); 60198c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_LED_CONFIG; 60208c2ecf20Sopenharmony_ci 60218c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 60228c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 60238c2ecf20Sopenharmony_ci if (IS_QLA8031(ha)) 60248c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3; 60258c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 60268c2ecf20Sopenharmony_ci mcp->flags = 0; 60278c2ecf20Sopenharmony_ci 60288c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 60298c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 60308c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1137, 60318c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 60328c2ecf20Sopenharmony_ci } else { 60338c2ecf20Sopenharmony_ci led_cfg[0] = mcp->mb[1]; 60348c2ecf20Sopenharmony_ci led_cfg[1] = mcp->mb[2]; 60358c2ecf20Sopenharmony_ci if (IS_QLA8031(ha)) { 60368c2ecf20Sopenharmony_ci led_cfg[2] = mcp->mb[3]; 60378c2ecf20Sopenharmony_ci led_cfg[3] = mcp->mb[4]; 60388c2ecf20Sopenharmony_ci led_cfg[4] = mcp->mb[5]; 60398c2ecf20Sopenharmony_ci led_cfg[5] = mcp->mb[6]; 60408c2ecf20Sopenharmony_ci } 60418c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138, 60428c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 60438c2ecf20Sopenharmony_ci } 60448c2ecf20Sopenharmony_ci 60458c2ecf20Sopenharmony_ci return rval; 60468c2ecf20Sopenharmony_ci} 60478c2ecf20Sopenharmony_ci 60488c2ecf20Sopenharmony_ciint 60498c2ecf20Sopenharmony_ciqla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable) 60508c2ecf20Sopenharmony_ci{ 60518c2ecf20Sopenharmony_ci int rval; 60528c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 60538c2ecf20Sopenharmony_ci mbx_cmd_t mc; 60548c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 60558c2ecf20Sopenharmony_ci 60568c2ecf20Sopenharmony_ci if (!IS_P3P_TYPE(ha)) 60578c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 60588c2ecf20Sopenharmony_ci 60598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127, 60608c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 60618c2ecf20Sopenharmony_ci 60628c2ecf20Sopenharmony_ci memset(mcp, 0, sizeof(mbx_cmd_t)); 60638c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_LED_CONFIG; 60648c2ecf20Sopenharmony_ci if (enable) 60658c2ecf20Sopenharmony_ci mcp->mb[7] = 0xE; 60668c2ecf20Sopenharmony_ci else 60678c2ecf20Sopenharmony_ci mcp->mb[7] = 0xD; 60688c2ecf20Sopenharmony_ci 60698c2ecf20Sopenharmony_ci mcp->out_mb = MBX_7|MBX_0; 60708c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 60718c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 60728c2ecf20Sopenharmony_ci mcp->flags = 0; 60738c2ecf20Sopenharmony_ci 60748c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 60758c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 60768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1128, 60778c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 60788c2ecf20Sopenharmony_ci } else { 60798c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129, 60808c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 60818c2ecf20Sopenharmony_ci } 60828c2ecf20Sopenharmony_ci 60838c2ecf20Sopenharmony_ci return rval; 60848c2ecf20Sopenharmony_ci} 60858c2ecf20Sopenharmony_ci 60868c2ecf20Sopenharmony_ciint 60878c2ecf20Sopenharmony_ciqla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) 60888c2ecf20Sopenharmony_ci{ 60898c2ecf20Sopenharmony_ci int rval; 60908c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 60918c2ecf20Sopenharmony_ci mbx_cmd_t mc; 60928c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 60938c2ecf20Sopenharmony_ci 60948c2ecf20Sopenharmony_ci if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 60958c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 60968c2ecf20Sopenharmony_ci 60978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, 60988c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 60998c2ecf20Sopenharmony_ci 61008c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_WRITE_REMOTE_REG; 61018c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(reg); 61028c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(reg); 61038c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(data); 61048c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(data); 61058c2ecf20Sopenharmony_ci mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 61068c2ecf20Sopenharmony_ci 61078c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 61088c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 61098c2ecf20Sopenharmony_ci mcp->flags = 0; 61108c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 61118c2ecf20Sopenharmony_ci 61128c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 61138c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1131, 61148c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 61158c2ecf20Sopenharmony_ci } else { 61168c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132, 61178c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 61188c2ecf20Sopenharmony_ci } 61198c2ecf20Sopenharmony_ci 61208c2ecf20Sopenharmony_ci return rval; 61218c2ecf20Sopenharmony_ci} 61228c2ecf20Sopenharmony_ci 61238c2ecf20Sopenharmony_ciint 61248c2ecf20Sopenharmony_ciqla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport) 61258c2ecf20Sopenharmony_ci{ 61268c2ecf20Sopenharmony_ci int rval; 61278c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 61288c2ecf20Sopenharmony_ci mbx_cmd_t mc; 61298c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 61308c2ecf20Sopenharmony_ci 61318c2ecf20Sopenharmony_ci if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 61328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b, 61338c2ecf20Sopenharmony_ci "Implicit LOGO Unsupported.\n"); 61348c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 61358c2ecf20Sopenharmony_ci } 61368c2ecf20Sopenharmony_ci 61378c2ecf20Sopenharmony_ci 61388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c, 61398c2ecf20Sopenharmony_ci "Entering %s.\n", __func__); 61408c2ecf20Sopenharmony_ci 61418c2ecf20Sopenharmony_ci /* Perform Implicit LOGO. */ 61428c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_PORT_LOGOUT; 61438c2ecf20Sopenharmony_ci mcp->mb[1] = fcport->loop_id; 61448c2ecf20Sopenharmony_ci mcp->mb[10] = BIT_15; 61458c2ecf20Sopenharmony_ci mcp->out_mb = MBX_10|MBX_1|MBX_0; 61468c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 61478c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 61488c2ecf20Sopenharmony_ci mcp->flags = 0; 61498c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 61508c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) 61518c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x113d, 61528c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 61538c2ecf20Sopenharmony_ci else 61548c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e, 61558c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 61568c2ecf20Sopenharmony_ci 61578c2ecf20Sopenharmony_ci return rval; 61588c2ecf20Sopenharmony_ci} 61598c2ecf20Sopenharmony_ci 61608c2ecf20Sopenharmony_ciint 61618c2ecf20Sopenharmony_ciqla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data) 61628c2ecf20Sopenharmony_ci{ 61638c2ecf20Sopenharmony_ci int rval; 61648c2ecf20Sopenharmony_ci mbx_cmd_t mc; 61658c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 61668c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 61678c2ecf20Sopenharmony_ci unsigned long retry_max_time = jiffies + (2 * HZ); 61688c2ecf20Sopenharmony_ci 61698c2ecf20Sopenharmony_ci if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 61708c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 61718c2ecf20Sopenharmony_ci 61728c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); 61738c2ecf20Sopenharmony_ci 61748c2ecf20Sopenharmony_ciretry_rd_reg: 61758c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_READ_REMOTE_REG; 61768c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(reg); 61778c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(reg); 61788c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 61798c2ecf20Sopenharmony_ci mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0; 61808c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 61818c2ecf20Sopenharmony_ci mcp->flags = 0; 61828c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 61838c2ecf20Sopenharmony_ci 61848c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 61858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x114c, 61868c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 61878c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 61888c2ecf20Sopenharmony_ci } else { 61898c2ecf20Sopenharmony_ci *data = (mcp->mb[3] | (mcp->mb[4] << 16)); 61908c2ecf20Sopenharmony_ci if (*data == QLA8XXX_BAD_VALUE) { 61918c2ecf20Sopenharmony_ci /* 61928c2ecf20Sopenharmony_ci * During soft-reset CAMRAM register reads might 61938c2ecf20Sopenharmony_ci * return 0xbad0bad0. So retry for MAX of 2 sec 61948c2ecf20Sopenharmony_ci * while reading camram registers. 61958c2ecf20Sopenharmony_ci */ 61968c2ecf20Sopenharmony_ci if (time_after(jiffies, retry_max_time)) { 61978c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1141, 61988c2ecf20Sopenharmony_ci "Failure to read CAMRAM register. " 61998c2ecf20Sopenharmony_ci "data=0x%x.\n", *data); 62008c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 62018c2ecf20Sopenharmony_ci } 62028c2ecf20Sopenharmony_ci msleep(100); 62038c2ecf20Sopenharmony_ci goto retry_rd_reg; 62048c2ecf20Sopenharmony_ci } 62058c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__); 62068c2ecf20Sopenharmony_ci } 62078c2ecf20Sopenharmony_ci 62088c2ecf20Sopenharmony_ci return rval; 62098c2ecf20Sopenharmony_ci} 62108c2ecf20Sopenharmony_ci 62118c2ecf20Sopenharmony_ciint 62128c2ecf20Sopenharmony_ciqla83xx_restart_nic_firmware(scsi_qla_host_t *vha) 62138c2ecf20Sopenharmony_ci{ 62148c2ecf20Sopenharmony_ci int rval; 62158c2ecf20Sopenharmony_ci mbx_cmd_t mc; 62168c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 62178c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 62188c2ecf20Sopenharmony_ci 62198c2ecf20Sopenharmony_ci if (!IS_QLA83XX(ha)) 62208c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 62218c2ecf20Sopenharmony_ci 62228c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__); 62238c2ecf20Sopenharmony_ci 62248c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE; 62258c2ecf20Sopenharmony_ci mcp->out_mb = MBX_0; 62268c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 62278c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 62288c2ecf20Sopenharmony_ci mcp->flags = 0; 62298c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 62308c2ecf20Sopenharmony_ci 62318c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 62328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1144, 62338c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x.\n", 62348c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1]); 62358c2ecf20Sopenharmony_ci qla2xxx_dump_fw(vha); 62368c2ecf20Sopenharmony_ci } else { 62378c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__); 62388c2ecf20Sopenharmony_ci } 62398c2ecf20Sopenharmony_ci 62408c2ecf20Sopenharmony_ci return rval; 62418c2ecf20Sopenharmony_ci} 62428c2ecf20Sopenharmony_ci 62438c2ecf20Sopenharmony_ciint 62448c2ecf20Sopenharmony_ciqla83xx_access_control(scsi_qla_host_t *vha, uint16_t options, 62458c2ecf20Sopenharmony_ci uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size) 62468c2ecf20Sopenharmony_ci{ 62478c2ecf20Sopenharmony_ci int rval; 62488c2ecf20Sopenharmony_ci mbx_cmd_t mc; 62498c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 62508c2ecf20Sopenharmony_ci uint8_t subcode = (uint8_t)options; 62518c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 62528c2ecf20Sopenharmony_ci 62538c2ecf20Sopenharmony_ci if (!IS_QLA8031(ha)) 62548c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 62558c2ecf20Sopenharmony_ci 62568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__); 62578c2ecf20Sopenharmony_ci 62588c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_ACCESS_CONTROL; 62598c2ecf20Sopenharmony_ci mcp->mb[1] = options; 62608c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 62618c2ecf20Sopenharmony_ci if (subcode & BIT_2) { 62628c2ecf20Sopenharmony_ci mcp->mb[2] = LSW(start_addr); 62638c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(start_addr); 62648c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(end_addr); 62658c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(end_addr); 62668c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2; 62678c2ecf20Sopenharmony_ci } 62688c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 62698c2ecf20Sopenharmony_ci if (!(subcode & (BIT_2 | BIT_5))) 62708c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_4|MBX_3; 62718c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 62728c2ecf20Sopenharmony_ci mcp->flags = 0; 62738c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 62748c2ecf20Sopenharmony_ci 62758c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 62768c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1147, 62778c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n", 62788c2ecf20Sopenharmony_ci rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], 62798c2ecf20Sopenharmony_ci mcp->mb[4]); 62808c2ecf20Sopenharmony_ci qla2xxx_dump_fw(vha); 62818c2ecf20Sopenharmony_ci } else { 62828c2ecf20Sopenharmony_ci if (subcode & BIT_5) 62838c2ecf20Sopenharmony_ci *sector_size = mcp->mb[1]; 62848c2ecf20Sopenharmony_ci else if (subcode & (BIT_6 | BIT_7)) { 62858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1148, 62868c2ecf20Sopenharmony_ci "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]); 62878c2ecf20Sopenharmony_ci } else if (subcode & (BIT_3 | BIT_4)) { 62888c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1149, 62898c2ecf20Sopenharmony_ci "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]); 62908c2ecf20Sopenharmony_ci } 62918c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__); 62928c2ecf20Sopenharmony_ci } 62938c2ecf20Sopenharmony_ci 62948c2ecf20Sopenharmony_ci return rval; 62958c2ecf20Sopenharmony_ci} 62968c2ecf20Sopenharmony_ci 62978c2ecf20Sopenharmony_ciint 62988c2ecf20Sopenharmony_ciqla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, 62998c2ecf20Sopenharmony_ci uint32_t size) 63008c2ecf20Sopenharmony_ci{ 63018c2ecf20Sopenharmony_ci int rval; 63028c2ecf20Sopenharmony_ci mbx_cmd_t mc; 63038c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 63048c2ecf20Sopenharmony_ci 63058c2ecf20Sopenharmony_ci if (!IS_MCTP_CAPABLE(vha->hw)) 63068c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 63078c2ecf20Sopenharmony_ci 63088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f, 63098c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 63108c2ecf20Sopenharmony_ci 63118c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; 63128c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(addr); 63138c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(req_dma); 63148c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(req_dma); 63158c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(size); 63168c2ecf20Sopenharmony_ci mcp->mb[5] = LSW(size); 63178c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(req_dma)); 63188c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(req_dma)); 63198c2ecf20Sopenharmony_ci mcp->mb[8] = MSW(addr); 63208c2ecf20Sopenharmony_ci /* Setting RAM ID to valid */ 63218c2ecf20Sopenharmony_ci /* For MCTP RAM ID is 0x40 */ 63228c2ecf20Sopenharmony_ci mcp->mb[10] = BIT_7 | 0x40; 63238c2ecf20Sopenharmony_ci 63248c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 63258c2ecf20Sopenharmony_ci MBX_0; 63268c2ecf20Sopenharmony_ci 63278c2ecf20Sopenharmony_ci mcp->in_mb = MBX_0; 63288c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 63298c2ecf20Sopenharmony_ci mcp->flags = 0; 63308c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 63318c2ecf20Sopenharmony_ci 63328c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 63338c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x114e, 63348c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 63358c2ecf20Sopenharmony_ci } else { 63368c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d, 63378c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 63388c2ecf20Sopenharmony_ci } 63398c2ecf20Sopenharmony_ci 63408c2ecf20Sopenharmony_ci return rval; 63418c2ecf20Sopenharmony_ci} 63428c2ecf20Sopenharmony_ci 63438c2ecf20Sopenharmony_ciint 63448c2ecf20Sopenharmony_ciqla26xx_dport_diagnostics(scsi_qla_host_t *vha, 63458c2ecf20Sopenharmony_ci void *dd_buf, uint size, uint options) 63468c2ecf20Sopenharmony_ci{ 63478c2ecf20Sopenharmony_ci int rval; 63488c2ecf20Sopenharmony_ci mbx_cmd_t mc; 63498c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 63508c2ecf20Sopenharmony_ci dma_addr_t dd_dma; 63518c2ecf20Sopenharmony_ci 63528c2ecf20Sopenharmony_ci if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && 63538c2ecf20Sopenharmony_ci !IS_QLA28XX(vha->hw)) 63548c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 63558c2ecf20Sopenharmony_ci 63568c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f, 63578c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 63588c2ecf20Sopenharmony_ci 63598c2ecf20Sopenharmony_ci dd_dma = dma_map_single(&vha->hw->pdev->dev, 63608c2ecf20Sopenharmony_ci dd_buf, size, DMA_FROM_DEVICE); 63618c2ecf20Sopenharmony_ci if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) { 63628c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n"); 63638c2ecf20Sopenharmony_ci return QLA_MEMORY_ALLOC_FAILED; 63648c2ecf20Sopenharmony_ci } 63658c2ecf20Sopenharmony_ci 63668c2ecf20Sopenharmony_ci memset(dd_buf, 0, size); 63678c2ecf20Sopenharmony_ci 63688c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_DPORT_DIAGNOSTICS; 63698c2ecf20Sopenharmony_ci mcp->mb[1] = options; 63708c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(LSD(dd_dma)); 63718c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(LSD(dd_dma)); 63728c2ecf20Sopenharmony_ci mcp->mb[6] = MSW(MSD(dd_dma)); 63738c2ecf20Sopenharmony_ci mcp->mb[7] = LSW(MSD(dd_dma)); 63748c2ecf20Sopenharmony_ci mcp->mb[8] = size; 63758c2ecf20Sopenharmony_ci mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 63768c2ecf20Sopenharmony_ci mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 63778c2ecf20Sopenharmony_ci mcp->buf_size = size; 63788c2ecf20Sopenharmony_ci mcp->flags = MBX_DMA_IN; 63798c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS * 4; 63808c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 63818c2ecf20Sopenharmony_ci 63828c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 63838c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval); 63848c2ecf20Sopenharmony_ci } else { 63858c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196, 63868c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 63878c2ecf20Sopenharmony_ci } 63888c2ecf20Sopenharmony_ci 63898c2ecf20Sopenharmony_ci dma_unmap_single(&vha->hw->pdev->dev, dd_dma, 63908c2ecf20Sopenharmony_ci size, DMA_FROM_DEVICE); 63918c2ecf20Sopenharmony_ci 63928c2ecf20Sopenharmony_ci return rval; 63938c2ecf20Sopenharmony_ci} 63948c2ecf20Sopenharmony_ci 63958c2ecf20Sopenharmony_cistatic void qla2x00_async_mb_sp_done(srb_t *sp, int res) 63968c2ecf20Sopenharmony_ci{ 63978c2ecf20Sopenharmony_ci sp->u.iocb_cmd.u.mbx.rc = res; 63988c2ecf20Sopenharmony_ci 63998c2ecf20Sopenharmony_ci complete(&sp->u.iocb_cmd.u.mbx.comp); 64008c2ecf20Sopenharmony_ci /* don't free sp here. Let the caller do the free */ 64018c2ecf20Sopenharmony_ci} 64028c2ecf20Sopenharmony_ci 64038c2ecf20Sopenharmony_ci/* 64048c2ecf20Sopenharmony_ci * This mailbox uses the iocb interface to send MB command. 64058c2ecf20Sopenharmony_ci * This allows non-critial (non chip setup) command to go 64068c2ecf20Sopenharmony_ci * out in parrallel. 64078c2ecf20Sopenharmony_ci */ 64088c2ecf20Sopenharmony_ciint qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) 64098c2ecf20Sopenharmony_ci{ 64108c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 64118c2ecf20Sopenharmony_ci srb_t *sp; 64128c2ecf20Sopenharmony_ci struct srb_iocb *c; 64138c2ecf20Sopenharmony_ci 64148c2ecf20Sopenharmony_ci if (!vha->hw->flags.fw_started) 64158c2ecf20Sopenharmony_ci goto done; 64168c2ecf20Sopenharmony_ci 64178c2ecf20Sopenharmony_ci sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 64188c2ecf20Sopenharmony_ci if (!sp) 64198c2ecf20Sopenharmony_ci goto done; 64208c2ecf20Sopenharmony_ci 64218c2ecf20Sopenharmony_ci sp->type = SRB_MB_IOCB; 64228c2ecf20Sopenharmony_ci sp->name = mb_to_str(mcp->mb[0]); 64238c2ecf20Sopenharmony_ci 64248c2ecf20Sopenharmony_ci c = &sp->u.iocb_cmd; 64258c2ecf20Sopenharmony_ci c->timeout = qla2x00_async_iocb_timeout; 64268c2ecf20Sopenharmony_ci init_completion(&c->u.mbx.comp); 64278c2ecf20Sopenharmony_ci 64288c2ecf20Sopenharmony_ci qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 64298c2ecf20Sopenharmony_ci 64308c2ecf20Sopenharmony_ci memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG); 64318c2ecf20Sopenharmony_ci 64328c2ecf20Sopenharmony_ci sp->done = qla2x00_async_mb_sp_done; 64338c2ecf20Sopenharmony_ci 64348c2ecf20Sopenharmony_ci rval = qla2x00_start_sp(sp); 64358c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 64368c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1018, 64378c2ecf20Sopenharmony_ci "%s: %s Failed submission. %x.\n", 64388c2ecf20Sopenharmony_ci __func__, sp->name, rval); 64398c2ecf20Sopenharmony_ci goto done_free_sp; 64408c2ecf20Sopenharmony_ci } 64418c2ecf20Sopenharmony_ci 64428c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n", 64438c2ecf20Sopenharmony_ci sp->name, sp->handle); 64448c2ecf20Sopenharmony_ci 64458c2ecf20Sopenharmony_ci wait_for_completion(&c->u.mbx.comp); 64468c2ecf20Sopenharmony_ci memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG); 64478c2ecf20Sopenharmony_ci 64488c2ecf20Sopenharmony_ci rval = c->u.mbx.rc; 64498c2ecf20Sopenharmony_ci switch (rval) { 64508c2ecf20Sopenharmony_ci case QLA_FUNCTION_TIMEOUT: 64518c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n", 64528c2ecf20Sopenharmony_ci __func__, sp->name, rval); 64538c2ecf20Sopenharmony_ci break; 64548c2ecf20Sopenharmony_ci case QLA_SUCCESS: 64558c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", 64568c2ecf20Sopenharmony_ci __func__, sp->name); 64578c2ecf20Sopenharmony_ci break; 64588c2ecf20Sopenharmony_ci default: 64598c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", 64608c2ecf20Sopenharmony_ci __func__, sp->name, rval); 64618c2ecf20Sopenharmony_ci break; 64628c2ecf20Sopenharmony_ci } 64638c2ecf20Sopenharmony_ci 64648c2ecf20Sopenharmony_cidone_free_sp: 64658c2ecf20Sopenharmony_ci sp->free(sp); 64668c2ecf20Sopenharmony_cidone: 64678c2ecf20Sopenharmony_ci return rval; 64688c2ecf20Sopenharmony_ci} 64698c2ecf20Sopenharmony_ci 64708c2ecf20Sopenharmony_ci/* 64718c2ecf20Sopenharmony_ci * qla24xx_gpdb_wait 64728c2ecf20Sopenharmony_ci * NOTE: Do not call this routine from DPC thread 64738c2ecf20Sopenharmony_ci */ 64748c2ecf20Sopenharmony_ciint qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) 64758c2ecf20Sopenharmony_ci{ 64768c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 64778c2ecf20Sopenharmony_ci dma_addr_t pd_dma; 64788c2ecf20Sopenharmony_ci struct port_database_24xx *pd; 64798c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 64808c2ecf20Sopenharmony_ci mbx_cmd_t mc; 64818c2ecf20Sopenharmony_ci 64828c2ecf20Sopenharmony_ci if (!vha->hw->flags.fw_started) 64838c2ecf20Sopenharmony_ci goto done; 64848c2ecf20Sopenharmony_ci 64858c2ecf20Sopenharmony_ci pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 64868c2ecf20Sopenharmony_ci if (pd == NULL) { 64878c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd047, 64888c2ecf20Sopenharmony_ci "Failed to allocate port database structure.\n"); 64898c2ecf20Sopenharmony_ci goto done_free_sp; 64908c2ecf20Sopenharmony_ci } 64918c2ecf20Sopenharmony_ci 64928c2ecf20Sopenharmony_ci memset(&mc, 0, sizeof(mc)); 64938c2ecf20Sopenharmony_ci mc.mb[0] = MBC_GET_PORT_DATABASE; 64948c2ecf20Sopenharmony_ci mc.mb[1] = fcport->loop_id; 64958c2ecf20Sopenharmony_ci mc.mb[2] = MSW(pd_dma); 64968c2ecf20Sopenharmony_ci mc.mb[3] = LSW(pd_dma); 64978c2ecf20Sopenharmony_ci mc.mb[6] = MSW(MSD(pd_dma)); 64988c2ecf20Sopenharmony_ci mc.mb[7] = LSW(MSD(pd_dma)); 64998c2ecf20Sopenharmony_ci mc.mb[9] = vha->vp_idx; 65008c2ecf20Sopenharmony_ci mc.mb[10] = opt; 65018c2ecf20Sopenharmony_ci 65028c2ecf20Sopenharmony_ci rval = qla24xx_send_mb_cmd(vha, &mc); 65038c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 65048c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1193, 65058c2ecf20Sopenharmony_ci "%s: %8phC fail\n", __func__, fcport->port_name); 65068c2ecf20Sopenharmony_ci goto done_free_sp; 65078c2ecf20Sopenharmony_ci } 65088c2ecf20Sopenharmony_ci 65098c2ecf20Sopenharmony_ci rval = __qla24xx_parse_gpdb(vha, fcport, pd); 65108c2ecf20Sopenharmony_ci 65118c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n", 65128c2ecf20Sopenharmony_ci __func__, fcport->port_name); 65138c2ecf20Sopenharmony_ci 65148c2ecf20Sopenharmony_cidone_free_sp: 65158c2ecf20Sopenharmony_ci if (pd) 65168c2ecf20Sopenharmony_ci dma_pool_free(ha->s_dma_pool, pd, pd_dma); 65178c2ecf20Sopenharmony_cidone: 65188c2ecf20Sopenharmony_ci return rval; 65198c2ecf20Sopenharmony_ci} 65208c2ecf20Sopenharmony_ci 65218c2ecf20Sopenharmony_ciint __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, 65228c2ecf20Sopenharmony_ci struct port_database_24xx *pd) 65238c2ecf20Sopenharmony_ci{ 65248c2ecf20Sopenharmony_ci int rval = QLA_SUCCESS; 65258c2ecf20Sopenharmony_ci uint64_t zero = 0; 65268c2ecf20Sopenharmony_ci u8 current_login_state, last_login_state; 65278c2ecf20Sopenharmony_ci 65288c2ecf20Sopenharmony_ci if (NVME_TARGET(vha->hw, fcport)) { 65298c2ecf20Sopenharmony_ci current_login_state = pd->current_login_state >> 4; 65308c2ecf20Sopenharmony_ci last_login_state = pd->last_login_state >> 4; 65318c2ecf20Sopenharmony_ci } else { 65328c2ecf20Sopenharmony_ci current_login_state = pd->current_login_state & 0xf; 65338c2ecf20Sopenharmony_ci last_login_state = pd->last_login_state & 0xf; 65348c2ecf20Sopenharmony_ci } 65358c2ecf20Sopenharmony_ci 65368c2ecf20Sopenharmony_ci /* Check for logged in state. */ 65378c2ecf20Sopenharmony_ci if (current_login_state != PDS_PRLI_COMPLETE) { 65388c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119a, 65398c2ecf20Sopenharmony_ci "Unable to verify login-state (%x/%x) for loop_id %x.\n", 65408c2ecf20Sopenharmony_ci current_login_state, last_login_state, fcport->loop_id); 65418c2ecf20Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 65428c2ecf20Sopenharmony_ci goto gpd_error_out; 65438c2ecf20Sopenharmony_ci } 65448c2ecf20Sopenharmony_ci 65458c2ecf20Sopenharmony_ci if (fcport->loop_id == FC_NO_LOOP_ID || 65468c2ecf20Sopenharmony_ci (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 65478c2ecf20Sopenharmony_ci memcmp(fcport->port_name, pd->port_name, 8))) { 65488c2ecf20Sopenharmony_ci /* We lost the device mid way. */ 65498c2ecf20Sopenharmony_ci rval = QLA_NOT_LOGGED_IN; 65508c2ecf20Sopenharmony_ci goto gpd_error_out; 65518c2ecf20Sopenharmony_ci } 65528c2ecf20Sopenharmony_ci 65538c2ecf20Sopenharmony_ci /* Names are little-endian. */ 65548c2ecf20Sopenharmony_ci memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 65558c2ecf20Sopenharmony_ci memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 65568c2ecf20Sopenharmony_ci 65578c2ecf20Sopenharmony_ci /* Get port_id of device. */ 65588c2ecf20Sopenharmony_ci fcport->d_id.b.domain = pd->port_id[0]; 65598c2ecf20Sopenharmony_ci fcport->d_id.b.area = pd->port_id[1]; 65608c2ecf20Sopenharmony_ci fcport->d_id.b.al_pa = pd->port_id[2]; 65618c2ecf20Sopenharmony_ci fcport->d_id.b.rsvd_1 = 0; 65628c2ecf20Sopenharmony_ci 65638c2ecf20Sopenharmony_ci if (NVME_TARGET(vha->hw, fcport)) { 65648c2ecf20Sopenharmony_ci fcport->port_type = FCT_NVME; 65658c2ecf20Sopenharmony_ci if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) 65668c2ecf20Sopenharmony_ci fcport->port_type |= FCT_NVME_INITIATOR; 65678c2ecf20Sopenharmony_ci if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 65688c2ecf20Sopenharmony_ci fcport->port_type |= FCT_NVME_TARGET; 65698c2ecf20Sopenharmony_ci if ((pd->prli_svc_param_word_3[0] & BIT_3) == 0) 65708c2ecf20Sopenharmony_ci fcport->port_type |= FCT_NVME_DISCOVERY; 65718c2ecf20Sopenharmony_ci } else { 65728c2ecf20Sopenharmony_ci /* If not target must be initiator or unknown type. */ 65738c2ecf20Sopenharmony_ci if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 65748c2ecf20Sopenharmony_ci fcport->port_type = FCT_INITIATOR; 65758c2ecf20Sopenharmony_ci else 65768c2ecf20Sopenharmony_ci fcport->port_type = FCT_TARGET; 65778c2ecf20Sopenharmony_ci } 65788c2ecf20Sopenharmony_ci /* Passback COS information. */ 65798c2ecf20Sopenharmony_ci fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? 65808c2ecf20Sopenharmony_ci FC_COS_CLASS2 : FC_COS_CLASS3; 65818c2ecf20Sopenharmony_ci 65828c2ecf20Sopenharmony_ci if (pd->prli_svc_param_word_3[0] & BIT_7) { 65838c2ecf20Sopenharmony_ci fcport->flags |= FCF_CONF_COMP_SUPPORTED; 65848c2ecf20Sopenharmony_ci fcport->conf_compl_supported = 1; 65858c2ecf20Sopenharmony_ci } 65868c2ecf20Sopenharmony_ci 65878c2ecf20Sopenharmony_cigpd_error_out: 65888c2ecf20Sopenharmony_ci return rval; 65898c2ecf20Sopenharmony_ci} 65908c2ecf20Sopenharmony_ci 65918c2ecf20Sopenharmony_ci/* 65928c2ecf20Sopenharmony_ci * qla24xx_gidlist__wait 65938c2ecf20Sopenharmony_ci * NOTE: don't call this routine from DPC thread. 65948c2ecf20Sopenharmony_ci */ 65958c2ecf20Sopenharmony_ciint qla24xx_gidlist_wait(struct scsi_qla_host *vha, 65968c2ecf20Sopenharmony_ci void *id_list, dma_addr_t id_list_dma, uint16_t *entries) 65978c2ecf20Sopenharmony_ci{ 65988c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 65998c2ecf20Sopenharmony_ci mbx_cmd_t mc; 66008c2ecf20Sopenharmony_ci 66018c2ecf20Sopenharmony_ci if (!vha->hw->flags.fw_started) 66028c2ecf20Sopenharmony_ci goto done; 66038c2ecf20Sopenharmony_ci 66048c2ecf20Sopenharmony_ci memset(&mc, 0, sizeof(mc)); 66058c2ecf20Sopenharmony_ci mc.mb[0] = MBC_GET_ID_LIST; 66068c2ecf20Sopenharmony_ci mc.mb[2] = MSW(id_list_dma); 66078c2ecf20Sopenharmony_ci mc.mb[3] = LSW(id_list_dma); 66088c2ecf20Sopenharmony_ci mc.mb[6] = MSW(MSD(id_list_dma)); 66098c2ecf20Sopenharmony_ci mc.mb[7] = LSW(MSD(id_list_dma)); 66108c2ecf20Sopenharmony_ci mc.mb[8] = 0; 66118c2ecf20Sopenharmony_ci mc.mb[9] = vha->vp_idx; 66128c2ecf20Sopenharmony_ci 66138c2ecf20Sopenharmony_ci rval = qla24xx_send_mb_cmd(vha, &mc); 66148c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 66158c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119b, 66168c2ecf20Sopenharmony_ci "%s: fail\n", __func__); 66178c2ecf20Sopenharmony_ci } else { 66188c2ecf20Sopenharmony_ci *entries = mc.mb[1]; 66198c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x119c, 66208c2ecf20Sopenharmony_ci "%s: done\n", __func__); 66218c2ecf20Sopenharmony_ci } 66228c2ecf20Sopenharmony_cidone: 66238c2ecf20Sopenharmony_ci return rval; 66248c2ecf20Sopenharmony_ci} 66258c2ecf20Sopenharmony_ci 66268c2ecf20Sopenharmony_ciint qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value) 66278c2ecf20Sopenharmony_ci{ 66288c2ecf20Sopenharmony_ci int rval; 66298c2ecf20Sopenharmony_ci mbx_cmd_t mc; 66308c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 66318c2ecf20Sopenharmony_ci 66328c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200, 66338c2ecf20Sopenharmony_ci "Entered %s\n", __func__); 66348c2ecf20Sopenharmony_ci 66358c2ecf20Sopenharmony_ci memset(mcp->mb, 0 , sizeof(mcp->mb)); 66368c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD; 66378c2ecf20Sopenharmony_ci mcp->mb[1] = 1; 66388c2ecf20Sopenharmony_ci mcp->mb[2] = value; 66398c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2 | MBX_1 | MBX_0; 66408c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2 | MBX_0; 66418c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 66428c2ecf20Sopenharmony_ci mcp->flags = 0; 66438c2ecf20Sopenharmony_ci 66448c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 66458c2ecf20Sopenharmony_ci 66468c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n", 66478c2ecf20Sopenharmony_ci (rval != QLA_SUCCESS) ? "Failed" : "Done", rval); 66488c2ecf20Sopenharmony_ci 66498c2ecf20Sopenharmony_ci return rval; 66508c2ecf20Sopenharmony_ci} 66518c2ecf20Sopenharmony_ci 66528c2ecf20Sopenharmony_ciint qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value) 66538c2ecf20Sopenharmony_ci{ 66548c2ecf20Sopenharmony_ci int rval; 66558c2ecf20Sopenharmony_ci mbx_cmd_t mc; 66568c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 66578c2ecf20Sopenharmony_ci 66588c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203, 66598c2ecf20Sopenharmony_ci "Entered %s\n", __func__); 66608c2ecf20Sopenharmony_ci 66618c2ecf20Sopenharmony_ci memset(mcp->mb, 0, sizeof(mcp->mb)); 66628c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD; 66638c2ecf20Sopenharmony_ci mcp->mb[1] = 0; 66648c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1 | MBX_0; 66658c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2 | MBX_0; 66668c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 66678c2ecf20Sopenharmony_ci mcp->flags = 0; 66688c2ecf20Sopenharmony_ci 66698c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 66708c2ecf20Sopenharmony_ci if (rval == QLA_SUCCESS) 66718c2ecf20Sopenharmony_ci *value = mc.mb[2]; 66728c2ecf20Sopenharmony_ci 66738c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n", 66748c2ecf20Sopenharmony_ci (rval != QLA_SUCCESS) ? "Failed" : "Done", rval); 66758c2ecf20Sopenharmony_ci 66768c2ecf20Sopenharmony_ci return rval; 66778c2ecf20Sopenharmony_ci} 66788c2ecf20Sopenharmony_ci 66798c2ecf20Sopenharmony_ciint 66808c2ecf20Sopenharmony_ciqla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count) 66818c2ecf20Sopenharmony_ci{ 66828c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 66838c2ecf20Sopenharmony_ci uint16_t iter, addr, offset; 66848c2ecf20Sopenharmony_ci dma_addr_t phys_addr; 66858c2ecf20Sopenharmony_ci int rval, c; 66868c2ecf20Sopenharmony_ci u8 *sfp_data; 66878c2ecf20Sopenharmony_ci 66888c2ecf20Sopenharmony_ci memset(ha->sfp_data, 0, SFP_DEV_SIZE); 66898c2ecf20Sopenharmony_ci addr = 0xa0; 66908c2ecf20Sopenharmony_ci phys_addr = ha->sfp_data_dma; 66918c2ecf20Sopenharmony_ci sfp_data = ha->sfp_data; 66928c2ecf20Sopenharmony_ci offset = c = 0; 66938c2ecf20Sopenharmony_ci 66948c2ecf20Sopenharmony_ci for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) { 66958c2ecf20Sopenharmony_ci if (iter == 4) { 66968c2ecf20Sopenharmony_ci /* Skip to next device address. */ 66978c2ecf20Sopenharmony_ci addr = 0xa2; 66988c2ecf20Sopenharmony_ci offset = 0; 66998c2ecf20Sopenharmony_ci } 67008c2ecf20Sopenharmony_ci 67018c2ecf20Sopenharmony_ci rval = qla2x00_read_sfp(vha, phys_addr, sfp_data, 67028c2ecf20Sopenharmony_ci addr, offset, SFP_BLOCK_SIZE, BIT_1); 67038c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 67048c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0x706d, 67058c2ecf20Sopenharmony_ci "Unable to read SFP data (%x/%x/%x).\n", rval, 67068c2ecf20Sopenharmony_ci addr, offset); 67078c2ecf20Sopenharmony_ci 67088c2ecf20Sopenharmony_ci return rval; 67098c2ecf20Sopenharmony_ci } 67108c2ecf20Sopenharmony_ci 67118c2ecf20Sopenharmony_ci if (buf && (c < count)) { 67128c2ecf20Sopenharmony_ci u16 sz; 67138c2ecf20Sopenharmony_ci 67148c2ecf20Sopenharmony_ci if ((count - c) >= SFP_BLOCK_SIZE) 67158c2ecf20Sopenharmony_ci sz = SFP_BLOCK_SIZE; 67168c2ecf20Sopenharmony_ci else 67178c2ecf20Sopenharmony_ci sz = count - c; 67188c2ecf20Sopenharmony_ci 67198c2ecf20Sopenharmony_ci memcpy(buf, sfp_data, sz); 67208c2ecf20Sopenharmony_ci buf += SFP_BLOCK_SIZE; 67218c2ecf20Sopenharmony_ci c += sz; 67228c2ecf20Sopenharmony_ci } 67238c2ecf20Sopenharmony_ci phys_addr += SFP_BLOCK_SIZE; 67248c2ecf20Sopenharmony_ci sfp_data += SFP_BLOCK_SIZE; 67258c2ecf20Sopenharmony_ci offset += SFP_BLOCK_SIZE; 67268c2ecf20Sopenharmony_ci } 67278c2ecf20Sopenharmony_ci 67288c2ecf20Sopenharmony_ci return rval; 67298c2ecf20Sopenharmony_ci} 67308c2ecf20Sopenharmony_ci 67318c2ecf20Sopenharmony_ciint qla24xx_res_count_wait(struct scsi_qla_host *vha, 67328c2ecf20Sopenharmony_ci uint16_t *out_mb, int out_mb_sz) 67338c2ecf20Sopenharmony_ci{ 67348c2ecf20Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 67358c2ecf20Sopenharmony_ci mbx_cmd_t mc; 67368c2ecf20Sopenharmony_ci 67378c2ecf20Sopenharmony_ci if (!vha->hw->flags.fw_started) 67388c2ecf20Sopenharmony_ci goto done; 67398c2ecf20Sopenharmony_ci 67408c2ecf20Sopenharmony_ci memset(&mc, 0, sizeof(mc)); 67418c2ecf20Sopenharmony_ci mc.mb[0] = MBC_GET_RESOURCE_COUNTS; 67428c2ecf20Sopenharmony_ci 67438c2ecf20Sopenharmony_ci rval = qla24xx_send_mb_cmd(vha, &mc); 67448c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 67458c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0xffff, 67468c2ecf20Sopenharmony_ci "%s: fail\n", __func__); 67478c2ecf20Sopenharmony_ci } else { 67488c2ecf20Sopenharmony_ci if (out_mb_sz <= SIZEOF_IOCB_MB_REG) 67498c2ecf20Sopenharmony_ci memcpy(out_mb, mc.mb, out_mb_sz); 67508c2ecf20Sopenharmony_ci else 67518c2ecf20Sopenharmony_ci memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG); 67528c2ecf20Sopenharmony_ci 67538c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0xffff, 67548c2ecf20Sopenharmony_ci "%s: done\n", __func__); 67558c2ecf20Sopenharmony_ci } 67568c2ecf20Sopenharmony_cidone: 67578c2ecf20Sopenharmony_ci return rval; 67588c2ecf20Sopenharmony_ci} 67598c2ecf20Sopenharmony_ci 67608c2ecf20Sopenharmony_ciint qla28xx_secure_flash_update(scsi_qla_host_t *vha, uint16_t opts, 67618c2ecf20Sopenharmony_ci uint16_t region, uint32_t len, dma_addr_t sfub_dma_addr, 67628c2ecf20Sopenharmony_ci uint32_t sfub_len) 67638c2ecf20Sopenharmony_ci{ 67648c2ecf20Sopenharmony_ci int rval; 67658c2ecf20Sopenharmony_ci mbx_cmd_t mc; 67668c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 67678c2ecf20Sopenharmony_ci 67688c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SECURE_FLASH_UPDATE; 67698c2ecf20Sopenharmony_ci mcp->mb[1] = opts; 67708c2ecf20Sopenharmony_ci mcp->mb[2] = region; 67718c2ecf20Sopenharmony_ci mcp->mb[3] = MSW(len); 67728c2ecf20Sopenharmony_ci mcp->mb[4] = LSW(len); 67738c2ecf20Sopenharmony_ci mcp->mb[5] = MSW(sfub_dma_addr); 67748c2ecf20Sopenharmony_ci mcp->mb[6] = LSW(sfub_dma_addr); 67758c2ecf20Sopenharmony_ci mcp->mb[7] = MSW(MSD(sfub_dma_addr)); 67768c2ecf20Sopenharmony_ci mcp->mb[8] = LSW(MSD(sfub_dma_addr)); 67778c2ecf20Sopenharmony_ci mcp->mb[9] = sfub_len; 67788c2ecf20Sopenharmony_ci mcp->out_mb = 67798c2ecf20Sopenharmony_ci MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 67808c2ecf20Sopenharmony_ci mcp->in_mb = MBX_2|MBX_1|MBX_0; 67818c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 67828c2ecf20Sopenharmony_ci mcp->flags = 0; 67838c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 67848c2ecf20Sopenharmony_ci 67858c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 67868c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s(%ld): failed rval 0x%x, %x %x %x", 67878c2ecf20Sopenharmony_ci __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1], 67888c2ecf20Sopenharmony_ci mcp->mb[2]); 67898c2ecf20Sopenharmony_ci } 67908c2ecf20Sopenharmony_ci 67918c2ecf20Sopenharmony_ci return rval; 67928c2ecf20Sopenharmony_ci} 67938c2ecf20Sopenharmony_ci 67948c2ecf20Sopenharmony_ciint qla2xxx_write_remote_register(scsi_qla_host_t *vha, uint32_t addr, 67958c2ecf20Sopenharmony_ci uint32_t data) 67968c2ecf20Sopenharmony_ci{ 67978c2ecf20Sopenharmony_ci int rval; 67988c2ecf20Sopenharmony_ci mbx_cmd_t mc; 67998c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 68008c2ecf20Sopenharmony_ci 68018c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 68028c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 68038c2ecf20Sopenharmony_ci 68048c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_WRITE_REMOTE_REG; 68058c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(addr); 68068c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(addr); 68078c2ecf20Sopenharmony_ci mcp->mb[3] = LSW(data); 68088c2ecf20Sopenharmony_ci mcp->mb[4] = MSW(data); 68098c2ecf20Sopenharmony_ci mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 68108c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 68118c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 68128c2ecf20Sopenharmony_ci mcp->flags = 0; 68138c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 68148c2ecf20Sopenharmony_ci 68158c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 68168c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e9, 68178c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 68188c2ecf20Sopenharmony_ci } else { 68198c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 68208c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 68218c2ecf20Sopenharmony_ci } 68228c2ecf20Sopenharmony_ci 68238c2ecf20Sopenharmony_ci return rval; 68248c2ecf20Sopenharmony_ci} 68258c2ecf20Sopenharmony_ci 68268c2ecf20Sopenharmony_ciint qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr, 68278c2ecf20Sopenharmony_ci uint32_t *data) 68288c2ecf20Sopenharmony_ci{ 68298c2ecf20Sopenharmony_ci int rval; 68308c2ecf20Sopenharmony_ci mbx_cmd_t mc; 68318c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 68328c2ecf20Sopenharmony_ci 68338c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 68348c2ecf20Sopenharmony_ci "Entered %s.\n", __func__); 68358c2ecf20Sopenharmony_ci 68368c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_READ_REMOTE_REG; 68378c2ecf20Sopenharmony_ci mcp->mb[1] = LSW(addr); 68388c2ecf20Sopenharmony_ci mcp->mb[2] = MSW(addr); 68398c2ecf20Sopenharmony_ci mcp->out_mb = MBX_2|MBX_1|MBX_0; 68408c2ecf20Sopenharmony_ci mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 68418c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 68428c2ecf20Sopenharmony_ci mcp->flags = 0; 68438c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 68448c2ecf20Sopenharmony_ci 68458c2ecf20Sopenharmony_ci *data = (uint32_t)((((uint32_t)mcp->mb[4]) << 16) | mcp->mb[3]); 68468c2ecf20Sopenharmony_ci 68478c2ecf20Sopenharmony_ci if (rval != QLA_SUCCESS) { 68488c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x10e9, 68498c2ecf20Sopenharmony_ci "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 68508c2ecf20Sopenharmony_ci } else { 68518c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 68528c2ecf20Sopenharmony_ci "Done %s.\n", __func__); 68538c2ecf20Sopenharmony_ci } 68548c2ecf20Sopenharmony_ci 68558c2ecf20Sopenharmony_ci return rval; 68568c2ecf20Sopenharmony_ci} 68578c2ecf20Sopenharmony_ci 68588c2ecf20Sopenharmony_ciint 68598c2ecf20Sopenharmony_ciql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led) 68608c2ecf20Sopenharmony_ci{ 68618c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 68628c2ecf20Sopenharmony_ci mbx_cmd_t mc; 68638c2ecf20Sopenharmony_ci mbx_cmd_t *mcp = &mc; 68648c2ecf20Sopenharmony_ci int rval; 68658c2ecf20Sopenharmony_ci 68668c2ecf20Sopenharmony_ci if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 68678c2ecf20Sopenharmony_ci return QLA_FUNCTION_FAILED; 68688c2ecf20Sopenharmony_ci 68698c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x7070, "Entered %s (options=%x).\n", 68708c2ecf20Sopenharmony_ci __func__, options); 68718c2ecf20Sopenharmony_ci 68728c2ecf20Sopenharmony_ci mcp->mb[0] = MBC_SET_GET_FC_LED_CONFIG; 68738c2ecf20Sopenharmony_ci mcp->mb[1] = options; 68748c2ecf20Sopenharmony_ci mcp->out_mb = MBX_1|MBX_0; 68758c2ecf20Sopenharmony_ci mcp->in_mb = MBX_1|MBX_0; 68768c2ecf20Sopenharmony_ci if (options & BIT_0) { 68778c2ecf20Sopenharmony_ci if (options & BIT_1) { 68788c2ecf20Sopenharmony_ci mcp->mb[2] = led[2]; 68798c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_2; 68808c2ecf20Sopenharmony_ci } 68818c2ecf20Sopenharmony_ci if (options & BIT_2) { 68828c2ecf20Sopenharmony_ci mcp->mb[3] = led[0]; 68838c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_3; 68848c2ecf20Sopenharmony_ci } 68858c2ecf20Sopenharmony_ci if (options & BIT_3) { 68868c2ecf20Sopenharmony_ci mcp->mb[4] = led[1]; 68878c2ecf20Sopenharmony_ci mcp->out_mb |= MBX_4; 68888c2ecf20Sopenharmony_ci } 68898c2ecf20Sopenharmony_ci } else { 68908c2ecf20Sopenharmony_ci mcp->in_mb |= MBX_4|MBX_3|MBX_2; 68918c2ecf20Sopenharmony_ci } 68928c2ecf20Sopenharmony_ci mcp->tov = MBX_TOV_SECONDS; 68938c2ecf20Sopenharmony_ci mcp->flags = 0; 68948c2ecf20Sopenharmony_ci rval = qla2x00_mailbox_command(vha, mcp); 68958c2ecf20Sopenharmony_ci if (rval) { 68968c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x7071, "Failed %s %x (mb=%x,%x)\n", 68978c2ecf20Sopenharmony_ci __func__, rval, mcp->mb[0], mcp->mb[1]); 68988c2ecf20Sopenharmony_ci return rval; 68998c2ecf20Sopenharmony_ci } 69008c2ecf20Sopenharmony_ci 69018c2ecf20Sopenharmony_ci if (options & BIT_0) { 69028c2ecf20Sopenharmony_ci ha->beacon_blink_led = 0; 69038c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x7072, "Done %s\n", __func__); 69048c2ecf20Sopenharmony_ci } else { 69058c2ecf20Sopenharmony_ci led[2] = mcp->mb[2]; 69068c2ecf20Sopenharmony_ci led[0] = mcp->mb[3]; 69078c2ecf20Sopenharmony_ci led[1] = mcp->mb[4]; 69088c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_mbx, vha, 0x7073, "Done %s (led=%x,%x,%x)\n", 69098c2ecf20Sopenharmony_ci __func__, led[0], led[1], led[2]); 69108c2ecf20Sopenharmony_ci } 69118c2ecf20Sopenharmony_ci 69128c2ecf20Sopenharmony_ci return rval; 69138c2ecf20Sopenharmony_ci} 6914