177adf3f0SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
3fa90c54fSAndrew Vasquez * QLogic Fibre Channel HBA Driver
4bd21eaf9SArmen Baloyan * Copyright (c) 2003-2014 QLogic Corporation
51da177e4SLinus Torvalds */
61da177e4SLinus Torvalds #include "qla_def.h"
72d70c103SNicholas Bellinger #include "qla_target.h"
81da177e4SLinus Torvalds
91da177e4SLinus Torvalds #include <linux/delay.h>
105a0e3ad6STejun Heo #include <linux/gfp.h>
111da177e4SLinus Torvalds
120d6a536cSJoe Carnuccio #ifdef CONFIG_PPC
130d6a536cSJoe Carnuccio #define IS_PPCARCH true
140d6a536cSJoe Carnuccio #else
150d6a536cSJoe Carnuccio #define IS_PPCARCH false
160d6a536cSJoe Carnuccio #endif
170d6a536cSJoe Carnuccio
1815f30a57SQuinn Tran static struct mb_cmd_name {
1915f30a57SQuinn Tran uint16_t cmd;
2015f30a57SQuinn Tran const char *str;
2115f30a57SQuinn Tran } mb_str[] = {
2215f30a57SQuinn Tran {MBC_GET_PORT_DATABASE, "GPDB"},
2315f30a57SQuinn Tran {MBC_GET_ID_LIST, "GIDList"},
2415f30a57SQuinn Tran {MBC_GET_LINK_PRIV_STATS, "Stats"},
2594d83e36SQuinn Tran {MBC_GET_RESOURCE_COUNTS, "ResCnt"},
2615f30a57SQuinn Tran };
2715f30a57SQuinn Tran
mb_to_str(uint16_t cmd)2815f30a57SQuinn Tran static const char *mb_to_str(uint16_t cmd)
2915f30a57SQuinn Tran {
3015f30a57SQuinn Tran int i;
3115f30a57SQuinn Tran struct mb_cmd_name *e;
3215f30a57SQuinn Tran
3315f30a57SQuinn Tran for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
3415f30a57SQuinn Tran e = mb_str + i;
3515f30a57SQuinn Tran if (cmd == e->cmd)
3615f30a57SQuinn Tran return e->str;
3715f30a57SQuinn Tran }
3815f30a57SQuinn Tran return "unknown";
3915f30a57SQuinn Tran }
4015f30a57SQuinn Tran
41ca825828SBart Van Assche static struct rom_cmd {
4277ddb94aShimanshu.madhani@cavium.com uint16_t cmd;
4377ddb94aShimanshu.madhani@cavium.com } rom_cmds[] = {
4477ddb94aShimanshu.madhani@cavium.com { MBC_LOAD_RAM },
4577ddb94aShimanshu.madhani@cavium.com { MBC_EXECUTE_FIRMWARE },
4677ddb94aShimanshu.madhani@cavium.com { MBC_READ_RAM_WORD },
4777ddb94aShimanshu.madhani@cavium.com { MBC_MAILBOX_REGISTER_TEST },
4877ddb94aShimanshu.madhani@cavium.com { MBC_VERIFY_CHECKSUM },
4977ddb94aShimanshu.madhani@cavium.com { MBC_GET_FIRMWARE_VERSION },
5077ddb94aShimanshu.madhani@cavium.com { MBC_LOAD_RISC_RAM },
5177ddb94aShimanshu.madhani@cavium.com { MBC_DUMP_RISC_RAM },
5277ddb94aShimanshu.madhani@cavium.com { MBC_LOAD_RISC_RAM_EXTENDED },
5377ddb94aShimanshu.madhani@cavium.com { MBC_DUMP_RISC_RAM_EXTENDED },
5477ddb94aShimanshu.madhani@cavium.com { MBC_WRITE_RAM_WORD_EXTENDED },
5577ddb94aShimanshu.madhani@cavium.com { MBC_READ_RAM_EXTENDED },
5677ddb94aShimanshu.madhani@cavium.com { MBC_GET_RESOURCE_COUNTS },
5777ddb94aShimanshu.madhani@cavium.com { MBC_SET_FIRMWARE_OPTION },
5877ddb94aShimanshu.madhani@cavium.com { MBC_MID_INITIALIZE_FIRMWARE },
5977ddb94aShimanshu.madhani@cavium.com { MBC_GET_FIRMWARE_STATE },
6077ddb94aShimanshu.madhani@cavium.com { MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
6177ddb94aShimanshu.madhani@cavium.com { MBC_GET_RETRY_COUNT },
6277ddb94aShimanshu.madhani@cavium.com { MBC_TRACE_CONTROL },
63b7edfa23SMichael Hernandez { MBC_INITIALIZE_MULTIQ },
641608cc4aSQuinn Tran { MBC_IOCB_COMMAND_A64 },
651608cc4aSQuinn Tran { MBC_GET_ADAPTER_LOOP_ID },
66e4e3a2ceSQuinn Tran { MBC_READ_SFP },
6762e9dd17SShyam Sundar { MBC_SET_RNID_PARAMS },
688777e431SQuinn Tran { MBC_GET_RNID_PARAMS },
698b4673baSQuinn Tran { MBC_GET_SET_ZIO_THRESHOLD },
7077ddb94aShimanshu.madhani@cavium.com };
7177ddb94aShimanshu.madhani@cavium.com
is_rom_cmd(uint16_t cmd)7277ddb94aShimanshu.madhani@cavium.com static int is_rom_cmd(uint16_t cmd)
7377ddb94aShimanshu.madhani@cavium.com {
7477ddb94aShimanshu.madhani@cavium.com int i;
7577ddb94aShimanshu.madhani@cavium.com struct rom_cmd *wc;
7677ddb94aShimanshu.madhani@cavium.com
7777ddb94aShimanshu.madhani@cavium.com for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
7877ddb94aShimanshu.madhani@cavium.com wc = rom_cmds + i;
7977ddb94aShimanshu.madhani@cavium.com if (wc->cmd == cmd)
8077ddb94aShimanshu.madhani@cavium.com return 1;
8177ddb94aShimanshu.madhani@cavium.com }
8277ddb94aShimanshu.madhani@cavium.com
8377ddb94aShimanshu.madhani@cavium.com return 0;
8477ddb94aShimanshu.madhani@cavium.com }
851da177e4SLinus Torvalds
861da177e4SLinus Torvalds /*
871da177e4SLinus Torvalds * qla2x00_mailbox_command
881da177e4SLinus Torvalds * Issue mailbox command and waits for completion.
891da177e4SLinus Torvalds *
901da177e4SLinus Torvalds * Input:
911da177e4SLinus Torvalds * ha = adapter block pointer.
921da177e4SLinus Torvalds * mcp = driver internal mbx struct pointer.
931da177e4SLinus Torvalds *
941da177e4SLinus Torvalds * Output:
951da177e4SLinus Torvalds * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
961da177e4SLinus Torvalds *
971da177e4SLinus Torvalds * Returns:
981da177e4SLinus Torvalds * 0 : QLA_SUCCESS = cmd performed success
991da177e4SLinus Torvalds * 1 : QLA_FUNCTION_FAILED (error encountered)
1001da177e4SLinus Torvalds * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
1011da177e4SLinus Torvalds *
1021da177e4SLinus Torvalds * Context:
1031da177e4SLinus Torvalds * Kernel context.
1041da177e4SLinus Torvalds */
1051da177e4SLinus Torvalds static int
qla2x00_mailbox_command(scsi_qla_host_t * vha,mbx_cmd_t * mcp)1067b867cf7SAnirban Chakraborty qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
1071da177e4SLinus Torvalds {
108d14e72fbSHimanshu Madhani int rval, i;
1091da177e4SLinus Torvalds unsigned long flags = 0;
110f73cb695SChad Dupuis device_reg_t *reg;
111daafc8d3SQuinn Tran uint8_t abort_active, eeh_delay;
1122c3dfe3fSSeokmann Ju uint8_t io_lock_on;
113cdbb0a4fSSantosh Vernekar uint16_t command = 0;
1141da177e4SLinus Torvalds uint16_t *iptr;
11537139da1SBart Van Assche __le16 __iomem *optr;
1161da177e4SLinus Torvalds uint32_t cnt;
1171da177e4SLinus Torvalds uint32_t mboxes;
1181da177e4SLinus Torvalds unsigned long wait_time;
1197b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
1207b867cf7SAnirban Chakraborty scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
121b2000805SQuinn Tran u32 chip_reset;
1222c3dfe3fSSeokmann Ju
123d14e72fbSHimanshu Madhani
1245e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
1257c3df132SSaurav Kashyap
126471298caSBart Van Assche if (ha->pdev->error_state == pci_channel_io_perm_failure) {
1275e19ed90SArun Easi ql_log(ql_log_warn, vha, 0x1001,
128471298caSBart Van Assche "PCI channel failed permanently, exiting.\n");
129b9b12f73SSeokmann Ju return QLA_FUNCTION_TIMEOUT;
1307c3df132SSaurav Kashyap }
131b9b12f73SSeokmann Ju
132a9083016SGiridhar Malavali if (vha->device_flags & DFLG_DEV_FAILED) {
1335e19ed90SArun Easi ql_log(ql_log_warn, vha, 0x1002,
1347c3df132SSaurav Kashyap "Device in failed state, exiting.\n");
135a9083016SGiridhar Malavali return QLA_FUNCTION_TIMEOUT;
136a9083016SGiridhar Malavali }
137a9083016SGiridhar Malavali
138783e0dc4SSawan Chandak /* if PCI error, then avoid mbx processing.*/
139ba175891SSawan Chandak if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) &&
140ba175891SSawan Chandak test_bit(UNLOADING, &base_vha->dpc_flags)) {
14183548fe2SQuinn Tran ql_log(ql_log_warn, vha, 0xd04e,
142783e0dc4SSawan Chandak "PCI error, exiting.\n");
143783e0dc4SSawan Chandak return QLA_FUNCTION_TIMEOUT;
144783e0dc4SSawan Chandak }
145daafc8d3SQuinn Tran eeh_delay = 0;
1462c3dfe3fSSeokmann Ju reg = ha->iobase;
1477b867cf7SAnirban Chakraborty io_lock_on = base_vha->flags.init_done;
1481da177e4SLinus Torvalds
1491da177e4SLinus Torvalds rval = QLA_SUCCESS;
1507b867cf7SAnirban Chakraborty abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
151b2000805SQuinn Tran chip_reset = ha->chip_reset;
1521c7c6357SAndrew Vasquez
15385880801SAndrew Vasquez if (ha->flags.pci_channel_io_perm_failure) {
1545e19ed90SArun Easi ql_log(ql_log_warn, vha, 0x1003,
1557c3df132SSaurav Kashyap "Perm failure on EEH timeout MBX, exiting.\n");
15685880801SAndrew Vasquez return QLA_FUNCTION_TIMEOUT;
15785880801SAndrew Vasquez }
15885880801SAndrew Vasquez
1597ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
160862cd01eSGiridhar Malavali /* Setting Link-Down error */
161862cd01eSGiridhar Malavali mcp->mb[0] = MBS_LINK_DOWN_ERROR;
1625e19ed90SArun Easi ql_log(ql_log_warn, vha, 0x1004,
1637c3df132SSaurav Kashyap "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
1641806fcd5SAndrew Vasquez return QLA_FUNCTION_TIMEOUT;
165862cd01eSGiridhar Malavali }
166862cd01eSGiridhar Malavali
16777ddb94aShimanshu.madhani@cavium.com /* check if ISP abort is active and return cmd with timeout */
168daafc8d3SQuinn Tran if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
16977ddb94aShimanshu.madhani@cavium.com test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
170daafc8d3SQuinn Tran test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
171daafc8d3SQuinn Tran !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) {
17277ddb94aShimanshu.madhani@cavium.com ql_log(ql_log_info, vha, 0x1005,
17377ddb94aShimanshu.madhani@cavium.com "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
17477ddb94aShimanshu.madhani@cavium.com mcp->mb[0]);
17577ddb94aShimanshu.madhani@cavium.com return QLA_FUNCTION_TIMEOUT;
17677ddb94aShimanshu.madhani@cavium.com }
17777ddb94aShimanshu.madhani@cavium.com
178b2000805SQuinn Tran atomic_inc(&ha->num_pend_mbx_stage1);
1791da177e4SLinus Torvalds /*
1801c7c6357SAndrew Vasquez * Wait for active mailbox commands to finish by waiting at most tov
1811c7c6357SAndrew Vasquez * seconds. This is to serialize actual issuing of mailbox cmds during
1821c7c6357SAndrew Vasquez * non ISP abort time.
1831da177e4SLinus Torvalds */
1848eca3f39SAndrew Vasquez if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
1851da177e4SLinus Torvalds /* Timeout occurred. Return error. */
18683548fe2SQuinn Tran ql_log(ql_log_warn, vha, 0xd035,
187d8c0d546SChad Dupuis "Cmd access timeout, cmd=0x%x, Exiting.\n",
188d8c0d546SChad Dupuis mcp->mb[0]);
189dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
190b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage1);
1911da177e4SLinus Torvalds return QLA_FUNCTION_TIMEOUT;
1921da177e4SLinus Torvalds }
193b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage1);
194daafc8d3SQuinn Tran if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||
195daafc8d3SQuinn Tran ha->flags.eeh_busy) {
196daafc8d3SQuinn Tran ql_log(ql_log_warn, vha, 0xd035,
197*29520a33SSaurav Kashyap "Purge mbox: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n",
198daafc8d3SQuinn Tran ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]);
199b2000805SQuinn Tran rval = QLA_ABORTED;
200b2000805SQuinn Tran goto premature_exit;
201b2000805SQuinn Tran }
2021da177e4SLinus Torvalds
203b6faaaf7SQuinn Tran
2041da177e4SLinus Torvalds /* Save mailbox command for debug */
2051da177e4SLinus Torvalds ha->mcp = mcp;
2061da177e4SLinus Torvalds
2075e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1006,
2087c3df132SSaurav Kashyap "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
2091da177e4SLinus Torvalds
2101da177e4SLinus Torvalds spin_lock_irqsave(&ha->hardware_lock, flags);
2111da177e4SLinus Torvalds
212b6faaaf7SQuinn Tran if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||
213b6faaaf7SQuinn Tran ha->flags.mbox_busy) {
214b2000805SQuinn Tran rval = QLA_ABORTED;
215b2000805SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock, flags);
216b2000805SQuinn Tran goto premature_exit;
217b2000805SQuinn Tran }
218b6faaaf7SQuinn Tran ha->flags.mbox_busy = 1;
219b2000805SQuinn Tran
2201da177e4SLinus Torvalds /* Load mailbox registers. */
2217ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha))
2227ffa5b93SBart Van Assche optr = ®->isp82.mailbox_in[0];
2237ec0effdSAtul Deshmukh else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
2247ffa5b93SBart Van Assche optr = ®->isp24.mailbox0;
2251c7c6357SAndrew Vasquez else
2267ffa5b93SBart Van Assche optr = MAILBOX_REG(ha, ®->isp, 0);
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds iptr = mcp->mb;
2291da177e4SLinus Torvalds command = mcp->mb[0];
2301da177e4SLinus Torvalds mboxes = mcp->out_mb;
2311da177e4SLinus Torvalds
2327b711623SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1111,
2330e31a2c8SJoe Carnuccio "Mailbox registers (OUT):\n");
2341da177e4SLinus Torvalds for (cnt = 0; cnt < ha->mbx_count; cnt++) {
2351da177e4SLinus Torvalds if (IS_QLA2200(ha) && cnt == 8)
2367ffa5b93SBart Van Assche optr = MAILBOX_REG(ha, ®->isp, 8);
2370e31a2c8SJoe Carnuccio if (mboxes & BIT_0) {
2380e31a2c8SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1112,
2390e31a2c8SJoe Carnuccio "mbox[%d]<-0x%04x\n", cnt, *iptr);
24004474d3aSBart Van Assche wrt_reg_word(optr, *iptr);
2416c96a3c7SBikash Hazarika } else {
2426c96a3c7SBikash Hazarika wrt_reg_word(optr, 0);
2430e31a2c8SJoe Carnuccio }
2441da177e4SLinus Torvalds
2451da177e4SLinus Torvalds mboxes >>= 1;
2461da177e4SLinus Torvalds optr++;
2471da177e4SLinus Torvalds iptr++;
2481da177e4SLinus Torvalds }
2491da177e4SLinus Torvalds
2505e19ed90SArun Easi ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
2517c3df132SSaurav Kashyap "I/O Address = %p.\n", optr);
2521da177e4SLinus Torvalds
2531da177e4SLinus Torvalds /* Issue set host interrupt command to send cmd out. */
2541da177e4SLinus Torvalds ha->flags.mbox_int = 0;
2551da177e4SLinus Torvalds clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
2561da177e4SLinus Torvalds
2571da177e4SLinus Torvalds /* Unlock mbx registers and wait for interrupt */
2585e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x100f,
2597c3df132SSaurav Kashyap "Going to unlock irq & waiting for interrupts. "
2607c3df132SSaurav Kashyap "jiffies=%lx.\n", jiffies);
2611da177e4SLinus Torvalds
2621da177e4SLinus Torvalds /* Wait for mbx cmd completion until timeout */
263b2000805SQuinn Tran atomic_inc(&ha->num_pend_mbx_stage2);
264124f85e6SAndrew Vasquez if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
2651da177e4SLinus Torvalds set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
2661da177e4SLinus Torvalds
26732a13df2SHimanshu Madhani if (IS_P3P_TYPE(ha))
26804474d3aSBart Van Assche wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING);
26932a13df2SHimanshu Madhani else if (IS_FWI2_CAPABLE(ha))
27004474d3aSBart Van Assche wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT);
2711c7c6357SAndrew Vasquez else
27204474d3aSBart Van Assche wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT);
2731da177e4SLinus Torvalds spin_unlock_irqrestore(&ha->hardware_lock, flags);
2741da177e4SLinus Torvalds
27577ddb94aShimanshu.madhani@cavium.com wait_time = jiffies;
276754d1243SGiridhar Malavali if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
277754d1243SGiridhar Malavali mcp->tov * HZ)) {
278f260694eSQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x117a,
279f260694eSQuinn Tran "cmd=%x Timeout.\n", command);
280f260694eSQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
281f260694eSQuinn Tran clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
282f260694eSQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock, flags);
283f260694eSQuinn Tran
284b6faaaf7SQuinn Tran if (chip_reset != ha->chip_reset) {
285daafc8d3SQuinn Tran eeh_delay = ha->flags.eeh_busy ? 1 : 0;
286daafc8d3SQuinn Tran
287b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
288b6faaaf7SQuinn Tran ha->flags.mbox_busy = 0;
289b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock,
290b6faaaf7SQuinn Tran flags);
291b6faaaf7SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage2);
292b6faaaf7SQuinn Tran rval = QLA_ABORTED;
293b6faaaf7SQuinn Tran goto premature_exit;
294b6faaaf7SQuinn Tran }
295b2000805SQuinn Tran } else if (ha->flags.purge_mbox ||
296b2000805SQuinn Tran chip_reset != ha->chip_reset) {
297daafc8d3SQuinn Tran eeh_delay = ha->flags.eeh_busy ? 1 : 0;
298daafc8d3SQuinn Tran
299b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
300b2000805SQuinn Tran ha->flags.mbox_busy = 0;
301b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock, flags);
302b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage2);
303b2000805SQuinn Tran rval = QLA_ABORTED;
304b2000805SQuinn Tran goto premature_exit;
305754d1243SGiridhar Malavali }
306b2000805SQuinn Tran
30777ddb94aShimanshu.madhani@cavium.com if (time_after(jiffies, wait_time + 5 * HZ))
30877ddb94aShimanshu.madhani@cavium.com ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
30977ddb94aShimanshu.madhani@cavium.com command, jiffies_to_msecs(jiffies - wait_time));
3101da177e4SLinus Torvalds } else {
3115e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1011,
3127c3df132SSaurav Kashyap "Cmd=%x Polling Mode.\n", command);
3131da177e4SLinus Torvalds
3147ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha)) {
31504474d3aSBart Van Assche if (rd_reg_dword(®->isp82.hint) &
316a9083016SGiridhar Malavali HINT_MBX_INT_PENDING) {
317b6faaaf7SQuinn Tran ha->flags.mbox_busy = 0;
318a9083016SGiridhar Malavali spin_unlock_irqrestore(&ha->hardware_lock,
319a9083016SGiridhar Malavali flags);
320b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage2);
3215e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1012,
3227c3df132SSaurav Kashyap "Pending mailbox timeout, exiting.\n");
323dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
324cdbb0a4fSSantosh Vernekar rval = QLA_FUNCTION_TIMEOUT;
325cdbb0a4fSSantosh Vernekar goto premature_exit;
326a9083016SGiridhar Malavali }
32704474d3aSBart Van Assche wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING);
328a9083016SGiridhar Malavali } else if (IS_FWI2_CAPABLE(ha))
32904474d3aSBart Van Assche wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT);
3301c7c6357SAndrew Vasquez else
33104474d3aSBart Van Assche wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT);
3321da177e4SLinus Torvalds spin_unlock_irqrestore(&ha->hardware_lock, flags);
3331da177e4SLinus Torvalds
3341da177e4SLinus Torvalds wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
3351da177e4SLinus Torvalds while (!ha->flags.mbox_int) {
336b2000805SQuinn Tran if (ha->flags.purge_mbox ||
337b2000805SQuinn Tran chip_reset != ha->chip_reset) {
338daafc8d3SQuinn Tran eeh_delay = ha->flags.eeh_busy ? 1 : 0;
339daafc8d3SQuinn Tran
340b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
341b2000805SQuinn Tran ha->flags.mbox_busy = 0;
342b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock,
343b6faaaf7SQuinn Tran flags);
344b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage2);
345b2000805SQuinn Tran rval = QLA_ABORTED;
346b2000805SQuinn Tran goto premature_exit;
347b2000805SQuinn Tran }
348b2000805SQuinn Tran
3491da177e4SLinus Torvalds if (time_after(jiffies, wait_time))
3501da177e4SLinus Torvalds break;
3511da177e4SLinus Torvalds
3521da177e4SLinus Torvalds /* Check for pending interrupts. */
35373208dfdSAnirban Chakraborty qla2x00_poll(ha->rsp_q_map[0]);
3541da177e4SLinus Torvalds
35585880801SAndrew Vasquez if (!ha->flags.mbox_int &&
35685880801SAndrew Vasquez !(IS_QLA2200(ha) &&
35785880801SAndrew Vasquez command == MBC_LOAD_RISC_RAM_EXTENDED))
35803ab2eabSandrew.vasquez@qlogic.com msleep(10);
3591da177e4SLinus Torvalds } /* while */
3605e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1013,
3617c3df132SSaurav Kashyap "Waited %d sec.\n",
3627c3df132SSaurav Kashyap (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
3631da177e4SLinus Torvalds }
364b2000805SQuinn Tran atomic_dec(&ha->num_pend_mbx_stage2);
3651da177e4SLinus Torvalds
3661da177e4SLinus Torvalds /* Check whether we timed out */
3671da177e4SLinus Torvalds if (ha->flags.mbox_int) {
3681da177e4SLinus Torvalds uint16_t *iptr2;
3691da177e4SLinus Torvalds
3705e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x1014,
3717c3df132SSaurav Kashyap "Cmd=%x completed.\n", command);
3721da177e4SLinus Torvalds
3731da177e4SLinus Torvalds /* Got interrupt. Clear the flag. */
3741da177e4SLinus Torvalds ha->flags.mbox_int = 0;
3751da177e4SLinus Torvalds clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3761da177e4SLinus Torvalds
3777ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
378b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
379cdbb0a4fSSantosh Vernekar ha->flags.mbox_busy = 0;
380b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock, flags);
381b6faaaf7SQuinn Tran
382cdbb0a4fSSantosh Vernekar /* Setting Link-Down error */
383cdbb0a4fSSantosh Vernekar mcp->mb[0] = MBS_LINK_DOWN_ERROR;
384cdbb0a4fSSantosh Vernekar ha->mcp = NULL;
385cdbb0a4fSSantosh Vernekar rval = QLA_FUNCTION_FAILED;
38683548fe2SQuinn Tran ql_log(ql_log_warn, vha, 0xd048,
3877c3df132SSaurav Kashyap "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
388cdbb0a4fSSantosh Vernekar goto premature_exit;
389cdbb0a4fSSantosh Vernekar }
390cdbb0a4fSSantosh Vernekar
391b3e9772dSBart Van Assche if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {
392b3e9772dSBart Van Assche ql_dbg(ql_dbg_mbx, vha, 0x11ff,
393b3e9772dSBart Van Assche "mb_out[0] = %#x <> %#x\n", ha->mailbox_out[0],
394b3e9772dSBart Van Assche MBS_COMMAND_COMPLETE);
3951da177e4SLinus Torvalds rval = QLA_FUNCTION_FAILED;
396b3e9772dSBart Van Assche }
3971da177e4SLinus Torvalds
3981da177e4SLinus Torvalds /* Load return mailbox registers. */
3991da177e4SLinus Torvalds iptr2 = mcp->mb;
4001da177e4SLinus Torvalds iptr = (uint16_t *)&ha->mailbox_out[0];
4011da177e4SLinus Torvalds mboxes = mcp->in_mb;
4020e31a2c8SJoe Carnuccio
4030e31a2c8SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1113,
4040e31a2c8SJoe Carnuccio "Mailbox registers (IN):\n");
4051da177e4SLinus Torvalds for (cnt = 0; cnt < ha->mbx_count; cnt++) {
4060e31a2c8SJoe Carnuccio if (mboxes & BIT_0) {
4071da177e4SLinus Torvalds *iptr2 = *iptr;
4080e31a2c8SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1114,
4090e31a2c8SJoe Carnuccio "mbox[%d]->0x%04x\n", cnt, *iptr2);
4100e31a2c8SJoe Carnuccio }
4111da177e4SLinus Torvalds
4121da177e4SLinus Torvalds mboxes >>= 1;
4131da177e4SLinus Torvalds iptr2++;
4141da177e4SLinus Torvalds iptr++;
4151da177e4SLinus Torvalds }
4161da177e4SLinus Torvalds } else {
4171da177e4SLinus Torvalds
4188d3c9c23SQuinn Tran uint16_t mb[8];
4198d3c9c23SQuinn Tran uint32_t ictrl, host_status, hccr;
420783e0dc4SSawan Chandak uint16_t w;
4211c7c6357SAndrew Vasquez
422e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
42304474d3aSBart Van Assche mb[0] = rd_reg_word(®->isp24.mailbox0);
42404474d3aSBart Van Assche mb[1] = rd_reg_word(®->isp24.mailbox1);
42504474d3aSBart Van Assche mb[2] = rd_reg_word(®->isp24.mailbox2);
42604474d3aSBart Van Assche mb[3] = rd_reg_word(®->isp24.mailbox3);
42704474d3aSBart Van Assche mb[7] = rd_reg_word(®->isp24.mailbox7);
42804474d3aSBart Van Assche ictrl = rd_reg_dword(®->isp24.ictrl);
42904474d3aSBart Van Assche host_status = rd_reg_dword(®->isp24.host_status);
43004474d3aSBart Van Assche hccr = rd_reg_dword(®->isp24.hccr);
4318d3c9c23SQuinn Tran
43283548fe2SQuinn Tran ql_log(ql_log_warn, vha, 0xd04c,
4338d3c9c23SQuinn Tran "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
4348d3c9c23SQuinn Tran "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",
4358d3c9c23SQuinn Tran command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],
4368d3c9c23SQuinn Tran mb[7], host_status, hccr);
437dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
4388d3c9c23SQuinn Tran
4391c7c6357SAndrew Vasquez } else {
4408d3c9c23SQuinn Tran mb[0] = RD_MAILBOX_REG(ha, ®->isp, 0);
44104474d3aSBart Van Assche ictrl = rd_reg_word(®->isp.ictrl);
4425e19ed90SArun Easi ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
4435f28d2d7SSaurav Kashyap "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
4448d3c9c23SQuinn Tran "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);
445dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
4468d3c9c23SQuinn Tran }
4475e19ed90SArun Easi ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
4481da177e4SLinus Torvalds
449783e0dc4SSawan Chandak /* Capture FW dump only, if PCI device active */
450783e0dc4SSawan Chandak if (!pci_channel_offline(vha->hw->pdev)) {
451783e0dc4SSawan Chandak pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
452b2000805SQuinn Tran if (w == 0xffff || ictrl == 0xffffffff ||
453b2000805SQuinn Tran (chip_reset != ha->chip_reset)) {
454783e0dc4SSawan Chandak /* This is special case if there is unload
455783e0dc4SSawan Chandak * of driver happening and if PCI device go
456783e0dc4SSawan Chandak * into bad state due to PCI error condition
457783e0dc4SSawan Chandak * then only PCI ERR flag would be set.
458783e0dc4SSawan Chandak * we will do premature exit for above case.
459783e0dc4SSawan Chandak */
460b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
461783e0dc4SSawan Chandak ha->flags.mbox_busy = 0;
462b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock,
463b6faaaf7SQuinn Tran flags);
464783e0dc4SSawan Chandak rval = QLA_FUNCTION_TIMEOUT;
465783e0dc4SSawan Chandak goto premature_exit;
466783e0dc4SSawan Chandak }
467783e0dc4SSawan Chandak
468783e0dc4SSawan Chandak /* Attempt to capture firmware dump for further
469783e0dc4SSawan Chandak * anallysis of the current formware state. we do not
470783e0dc4SSawan Chandak * need to do this if we are intentionally generating
471783e0dc4SSawan Chandak * a dump
472f55bfc88SChad Dupuis */
473b8eb4136SChad Dupuis if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
4748ae17876SBart Van Assche qla2xxx_dump_fw(vha);
4751da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT;
4761da177e4SLinus Torvalds }
477783e0dc4SSawan Chandak }
478b6faaaf7SQuinn Tran spin_lock_irqsave(&ha->hardware_lock, flags);
4791da177e4SLinus Torvalds ha->flags.mbox_busy = 0;
480b6faaaf7SQuinn Tran spin_unlock_irqrestore(&ha->hardware_lock, flags);
4811da177e4SLinus Torvalds
4821da177e4SLinus Torvalds /* Clean up */
4831da177e4SLinus Torvalds ha->mcp = NULL;
4841da177e4SLinus Torvalds
485124f85e6SAndrew Vasquez if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
4865e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x101a,
4877c3df132SSaurav Kashyap "Checking for additional resp interrupt.\n");
4881da177e4SLinus Torvalds
4891da177e4SLinus Torvalds /* polling mode for non isp_abort commands. */
49073208dfdSAnirban Chakraborty qla2x00_poll(ha->rsp_q_map[0]);
4911da177e4SLinus Torvalds }
4921da177e4SLinus Torvalds
4931c7c6357SAndrew Vasquez if (rval == QLA_FUNCTION_TIMEOUT &&
4941c7c6357SAndrew Vasquez mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
49585880801SAndrew Vasquez if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
49685880801SAndrew Vasquez ha->flags.eeh_busy) {
4971da177e4SLinus Torvalds /* not in dpc. schedule it for dpc to take over. */
4985e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x101b,
4997c3df132SSaurav Kashyap "Timeout, schedule isp_abort_needed.\n");
500cdbb0a4fSSantosh Vernekar
501cdbb0a4fSSantosh Vernekar if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
502cdbb0a4fSSantosh Vernekar !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
503cdbb0a4fSSantosh Vernekar !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
50463154916SGiridhar Malavali if (IS_QLA82XX(ha)) {
50563154916SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x112a,
50663154916SGiridhar Malavali "disabling pause transmit on port "
50763154916SGiridhar Malavali "0 & 1.\n");
50863154916SGiridhar Malavali qla82xx_wr_32(ha,
50963154916SGiridhar Malavali QLA82XX_CRB_NIU + 0x98,
51063154916SGiridhar Malavali CRB_NIU_XG_PAUSE_CTL_P0|
51163154916SGiridhar Malavali CRB_NIU_XG_PAUSE_CTL_P1);
51263154916SGiridhar Malavali }
5137c3df132SSaurav Kashyap ql_log(ql_log_info, base_vha, 0x101c,
51424d9ee85SMasanari Iida "Mailbox cmd timeout occurred, cmd=0x%x, "
515d8c0d546SChad Dupuis "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
516d8c0d546SChad Dupuis "abort.\n", command, mcp->mb[0],
517cdbb0a4fSSantosh Vernekar ha->flags.eeh_busy);
518dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
519cdbb0a4fSSantosh Vernekar set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
5207b867cf7SAnirban Chakraborty qla2xxx_wake_dpc(vha);
521cdbb0a4fSSantosh Vernekar }
522710bc78fSQuinn Tran } else if (current == ha->dpc_thread) {
5231da177e4SLinus Torvalds /* call abort directly since we are in the DPC thread */
5245e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x101d,
5257c3df132SSaurav Kashyap "Timeout, calling abort_isp.\n");
526cdbb0a4fSSantosh Vernekar
527cdbb0a4fSSantosh Vernekar if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
528cdbb0a4fSSantosh Vernekar !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
529cdbb0a4fSSantosh Vernekar !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
53063154916SGiridhar Malavali if (IS_QLA82XX(ha)) {
53163154916SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x112b,
53263154916SGiridhar Malavali "disabling pause transmit on port "
53363154916SGiridhar Malavali "0 & 1.\n");
53463154916SGiridhar Malavali qla82xx_wr_32(ha,
53563154916SGiridhar Malavali QLA82XX_CRB_NIU + 0x98,
53663154916SGiridhar Malavali CRB_NIU_XG_PAUSE_CTL_P0|
53763154916SGiridhar Malavali CRB_NIU_XG_PAUSE_CTL_P1);
53863154916SGiridhar Malavali }
5397c3df132SSaurav Kashyap ql_log(ql_log_info, base_vha, 0x101e,
54024d9ee85SMasanari Iida "Mailbox cmd timeout occurred, cmd=0x%x, "
541d8c0d546SChad Dupuis "mb[0]=0x%x. Scheduling ISP abort ",
542d8c0d546SChad Dupuis command, mcp->mb[0]);
543dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
544cdbb0a4fSSantosh Vernekar set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
545cdbb0a4fSSantosh Vernekar clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
546d3360960SGiridhar Malavali /* Allow next mbx cmd to come in. */
547d3360960SGiridhar Malavali complete(&ha->mbx_cmd_comp);
548daafc8d3SQuinn Tran if (ha->isp_ops->abort_isp(vha) &&
549daafc8d3SQuinn Tran !ha->flags.eeh_busy) {
5501c7c6357SAndrew Vasquez /* Failed. retry later. */
551cdbb0a4fSSantosh Vernekar set_bit(ISP_ABORT_NEEDED,
552cdbb0a4fSSantosh Vernekar &vha->dpc_flags);
5531da177e4SLinus Torvalds }
554cdbb0a4fSSantosh Vernekar clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
5555e19ed90SArun Easi ql_dbg(ql_dbg_mbx, vha, 0x101f,
5567c3df132SSaurav Kashyap "Finished abort_isp.\n");
557d3360960SGiridhar Malavali goto mbx_done;
558cdbb0a4fSSantosh Vernekar }
5591da177e4SLinus Torvalds }
5601da177e4SLinus Torvalds }
5611da177e4SLinus Torvalds
562cdbb0a4fSSantosh Vernekar premature_exit:
5631da177e4SLinus Torvalds /* Allow next mbx cmd to come in. */
5640b05a1f0SMarcus Barrow complete(&ha->mbx_cmd_comp);
5651da177e4SLinus Torvalds
566d3360960SGiridhar Malavali mbx_done:
567b2000805SQuinn Tran if (rval == QLA_ABORTED) {
568b2000805SQuinn Tran ql_log(ql_log_info, vha, 0xd035,
569b2000805SQuinn Tran "Chip Reset in progress. Purging Mbox cmd=0x%x.\n",
570b2000805SQuinn Tran mcp->mb[0]);
571b2000805SQuinn Tran } else if (rval) {
572050dc76aSJoe Carnuccio if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
5733f918ffaSBart Van Assche pr_warn("%s [%s]-%04x:%ld: **** Failed=%x", QL_MSGHDR,
574050dc76aSJoe Carnuccio dev_name(&ha->pdev->dev), 0x1020+0x800,
5753f918ffaSBart Van Assche vha->host_no, rval);
576050dc76aSJoe Carnuccio mboxes = mcp->in_mb;
577050dc76aSJoe Carnuccio cnt = 4;
578050dc76aSJoe Carnuccio for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1)
579050dc76aSJoe Carnuccio if (mboxes & BIT_0) {
580050dc76aSJoe Carnuccio printk(" mb[%u]=%x", i, mcp->mb[i]);
581050dc76aSJoe Carnuccio cnt--;
582050dc76aSJoe Carnuccio }
583050dc76aSJoe Carnuccio pr_warn(" cmd=%x ****\n", command);
584050dc76aSJoe Carnuccio }
585f7e59e99SMeelis Roos if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {
58675d560e0SSawan Chandak ql_dbg(ql_dbg_mbx, vha, 0x1198,
587050dc76aSJoe Carnuccio "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
58804474d3aSBart Van Assche rd_reg_dword(®->isp24.host_status),
58904474d3aSBart Van Assche rd_reg_dword(®->isp24.ictrl),
59004474d3aSBart Van Assche rd_reg_dword(®->isp24.istatus));
5911da177e4SLinus Torvalds } else {
592f7e59e99SMeelis Roos ql_dbg(ql_dbg_mbx, vha, 0x1206,
593f7e59e99SMeelis Roos "ctrl_status=%#x ictrl=%#x istatus=%#x\n",
59404474d3aSBart Van Assche rd_reg_word(®->isp.ctrl_status),
59504474d3aSBart Van Assche rd_reg_word(®->isp.ictrl),
59604474d3aSBart Van Assche rd_reg_word(®->isp.istatus));
597f7e59e99SMeelis Roos }
598f7e59e99SMeelis Roos } else {
5997c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
6001da177e4SLinus Torvalds }
6011da177e4SLinus Torvalds
602daafc8d3SQuinn Tran i = 500;
603daafc8d3SQuinn Tran while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) {
604daafc8d3SQuinn Tran /*
605daafc8d3SQuinn Tran * The caller of this mailbox encounter pci error.
606daafc8d3SQuinn Tran * Hold the thread until PCIE link reset complete to make
607daafc8d3SQuinn Tran * sure caller does not unmap dma while recovery is
608daafc8d3SQuinn Tran * in progress.
609daafc8d3SQuinn Tran */
610daafc8d3SQuinn Tran msleep(1);
611daafc8d3SQuinn Tran i--;
612daafc8d3SQuinn Tran }
6131da177e4SLinus Torvalds return rval;
6141da177e4SLinus Torvalds }
6151da177e4SLinus Torvalds
6161da177e4SLinus Torvalds int
qla2x00_load_ram(scsi_qla_host_t * vha,dma_addr_t req_dma,uint32_t risc_addr,uint32_t risc_code_size)6177b867cf7SAnirban Chakraborty qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
618590f98e5Sandrew.vasquez@qlogic.com uint32_t risc_code_size)
6191da177e4SLinus Torvalds {
6201da177e4SLinus Torvalds int rval;
6217b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
6221da177e4SLinus Torvalds mbx_cmd_t mc;
6231da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
6241da177e4SLinus Torvalds
6255f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
6265f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
6271da177e4SLinus Torvalds
628e428924cSAndrew Vasquez if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
6291da177e4SLinus Torvalds mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
630590f98e5Sandrew.vasquez@qlogic.com mcp->mb[8] = MSW(risc_addr);
631590f98e5Sandrew.vasquez@qlogic.com mcp->out_mb = MBX_8|MBX_0;
632590f98e5Sandrew.vasquez@qlogic.com } else {
633590f98e5Sandrew.vasquez@qlogic.com mcp->mb[0] = MBC_LOAD_RISC_RAM;
634590f98e5Sandrew.vasquez@qlogic.com mcp->out_mb = MBX_0;
635590f98e5Sandrew.vasquez@qlogic.com }
6361da177e4SLinus Torvalds mcp->mb[1] = LSW(risc_addr);
6371da177e4SLinus Torvalds mcp->mb[2] = MSW(req_dma);
6381da177e4SLinus Torvalds mcp->mb[3] = LSW(req_dma);
6391da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(req_dma));
6401da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(req_dma));
641590f98e5Sandrew.vasquez@qlogic.com mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
642e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
6431c7c6357SAndrew Vasquez mcp->mb[4] = MSW(risc_code_size);
6441c7c6357SAndrew Vasquez mcp->mb[5] = LSW(risc_code_size);
6451c7c6357SAndrew Vasquez mcp->out_mb |= MBX_5|MBX_4;
6461c7c6357SAndrew Vasquez } else {
6471c7c6357SAndrew Vasquez mcp->mb[4] = LSW(risc_code_size);
6481c7c6357SAndrew Vasquez mcp->out_mb |= MBX_4;
6491da177e4SLinus Torvalds }
6501da177e4SLinus Torvalds
6512a3192a3SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
652b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
6531c7c6357SAndrew Vasquez mcp->flags = 0;
6547b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
6551c7c6357SAndrew Vasquez
6561da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
6577c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1023,
6582a3192a3SJoe Carnuccio "Failed=%x mb[0]=%x mb[1]=%x.\n",
6592a3192a3SJoe Carnuccio rval, mcp->mb[0], mcp->mb[1]);
660dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
6611da177e4SLinus Torvalds } else {
6625f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
6635f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
6641da177e4SLinus Torvalds }
6651da177e4SLinus Torvalds
6661da177e4SLinus Torvalds return rval;
6671da177e4SLinus Torvalds }
6681da177e4SLinus Torvalds
669e84067d7SDuane Grigsby #define NVME_ENABLE_FLAG BIT_3
670d07b75baSQuinn Tran #define EDIF_HW_SUPPORT BIT_10
671e84067d7SDuane Grigsby
6721da177e4SLinus Torvalds /*
6731da177e4SLinus Torvalds * qla2x00_execute_fw
6741da177e4SLinus Torvalds * Start adapter firmware.
6751da177e4SLinus Torvalds *
6761da177e4SLinus Torvalds * Input:
6771da177e4SLinus Torvalds * ha = adapter block pointer.
6781da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
6791da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
6801da177e4SLinus Torvalds *
6811da177e4SLinus Torvalds * Returns:
6821da177e4SLinus Torvalds * qla2x00 local function return status code.
6831da177e4SLinus Torvalds *
6841da177e4SLinus Torvalds * Context:
6851da177e4SLinus Torvalds * Kernel context.
6861da177e4SLinus Torvalds */
6871da177e4SLinus Torvalds int
qla2x00_execute_fw(scsi_qla_host_t * vha,uint32_t risc_addr)6887b867cf7SAnirban Chakraborty qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
6891da177e4SLinus Torvalds {
6901da177e4SLinus Torvalds int rval;
6917b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
6921da177e4SLinus Torvalds mbx_cmd_t mc;
6931da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
694cad9c2d2SQuinn Tran u8 semaphore = 0;
695cad9c2d2SQuinn Tran #define EXE_FW_FORCE_SEMAPHORE BIT_7
696355f5ffeSQuinn Tran u8 retry = 5;
6971da177e4SLinus Torvalds
6985f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
6995f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
7001da177e4SLinus Torvalds
701cad9c2d2SQuinn Tran again:
7021da177e4SLinus Torvalds mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
7031c7c6357SAndrew Vasquez mcp->out_mb = MBX_0;
7041c7c6357SAndrew Vasquez mcp->in_mb = MBX_0;
705e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
7061c7c6357SAndrew Vasquez mcp->mb[1] = MSW(risc_addr);
7071c7c6357SAndrew Vasquez mcp->mb[2] = LSW(risc_addr);
7081c7c6357SAndrew Vasquez mcp->mb[3] = 0;
709e4e3a2ceSQuinn Tran mcp->mb[4] = 0;
710c2ff2a36SHimanshu Madhani mcp->mb[11] = 0;
711b0f18eeeSAndrew Vasquez
712b0f18eeeSAndrew Vasquez /* Enable BPM? */
713b0f18eeeSAndrew Vasquez if (ha->flags.lr_detected) {
714b0f18eeeSAndrew Vasquez mcp->mb[4] = BIT_0;
715b0f18eeeSAndrew Vasquez if (IS_BPM_RANGE_CAPABLE(ha))
716e4e3a2ceSQuinn Tran mcp->mb[4] |=
717b0f18eeeSAndrew Vasquez ha->lr_distance << LR_DIST_FW_POS;
718e4e3a2ceSQuinn Tran }
719b0d6cabdSHimanshu Madhani
720ecc89f25SJoe Carnuccio if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha)))
721e84067d7SDuane Grigsby mcp->mb[4] |= NVME_ENABLE_FLAG;
722e84067d7SDuane Grigsby
723ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
72492d4408eSSawan Chandak struct nvram_81xx *nv = ha->nvram;
72592d4408eSSawan Chandak /* set minimum speed if specified in nvram */
72672a92df2SJoe Carnuccio if (nv->min_supported_speed >= 2 &&
72772a92df2SJoe Carnuccio nv->min_supported_speed <= 5) {
72892d4408eSSawan Chandak mcp->mb[4] |= BIT_4;
72972a92df2SJoe Carnuccio mcp->mb[11] |= nv->min_supported_speed & 0xF;
73092d4408eSSawan Chandak mcp->out_mb |= MBX_11;
73192d4408eSSawan Chandak mcp->in_mb |= BIT_5;
73272a92df2SJoe Carnuccio vha->min_supported_speed =
73372a92df2SJoe Carnuccio nv->min_supported_speed;
73492d4408eSSawan Chandak }
7350d6a536cSJoe Carnuccio
7360d6a536cSJoe Carnuccio if (IS_PPCARCH)
7370d6a536cSJoe Carnuccio mcp->mb[11] |= BIT_4;
73892d4408eSSawan Chandak }
73992d4408eSSawan Chandak
740b0d6cabdSHimanshu Madhani if (ha->flags.exlogins_enabled)
741b0d6cabdSHimanshu Madhani mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
742b0d6cabdSHimanshu Madhani
7432f56a7f1SHimanshu Madhani if (ha->flags.exchoffld_enabled)
7442f56a7f1SHimanshu Madhani mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
7452f56a7f1SHimanshu Madhani
746cad9c2d2SQuinn Tran if (semaphore)
747cad9c2d2SQuinn Tran mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE;
748cad9c2d2SQuinn Tran
749c2ff2a36SHimanshu Madhani mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;
75044d01857SQuinn Tran mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1;
7511c7c6357SAndrew Vasquez } else {
7521c7c6357SAndrew Vasquez mcp->mb[1] = LSW(risc_addr);
7531c7c6357SAndrew Vasquez mcp->out_mb |= MBX_1;
7541da177e4SLinus Torvalds if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
7551da177e4SLinus Torvalds mcp->mb[2] = 0;
7561da177e4SLinus Torvalds mcp->out_mb |= MBX_2;
7571da177e4SLinus Torvalds }
7581c7c6357SAndrew Vasquez }
7591da177e4SLinus Torvalds
760b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
7611da177e4SLinus Torvalds mcp->flags = 0;
7627b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
7631da177e4SLinus Torvalds
7641c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
765cad9c2d2SQuinn Tran if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR &&
766cad9c2d2SQuinn Tran mcp->mb[1] == 0x27 && retry) {
767cad9c2d2SQuinn Tran semaphore = 1;
768cad9c2d2SQuinn Tran retry--;
769cad9c2d2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x1026,
770cad9c2d2SQuinn Tran "Exe FW: force semaphore.\n");
771cad9c2d2SQuinn Tran goto again;
772cad9c2d2SQuinn Tran }
773cad9c2d2SQuinn Tran
774355f5ffeSQuinn Tran if (retry) {
775355f5ffeSQuinn Tran retry--;
776355f5ffeSQuinn Tran ql_dbg(ql_dbg_async, vha, 0x509d,
777355f5ffeSQuinn Tran "Exe FW retry: mb[0]=%x retry[%d]\n", mcp->mb[0], retry);
778355f5ffeSQuinn Tran goto again;
779355f5ffeSQuinn Tran }
7807c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1026,
7817c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
782dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
78372a92df2SJoe Carnuccio return rval;
78472a92df2SJoe Carnuccio }
78572a92df2SJoe Carnuccio
78672a92df2SJoe Carnuccio if (!IS_FWI2_CAPABLE(ha))
78772a92df2SJoe Carnuccio goto done;
78872a92df2SJoe Carnuccio
7891f4c7c38SJoe Carnuccio ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];
7901f4c7c38SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x119a,
7911f4c7c38SJoe Carnuccio "fw_ability_mask=%x.\n", ha->fw_ability_mask);
79272a92df2SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1027, "exchanges=%x.\n", mcp->mb[1]);
79372a92df2SJoe Carnuccio if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
79472a92df2SJoe Carnuccio ha->max_supported_speed = mcp->mb[2] & (BIT_0|BIT_1);
79572a92df2SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x119b, "max_supported_speed=%s.\n",
79672a92df2SJoe Carnuccio ha->max_supported_speed == 0 ? "16Gps" :
79772a92df2SJoe Carnuccio ha->max_supported_speed == 1 ? "32Gps" :
79872a92df2SJoe Carnuccio ha->max_supported_speed == 2 ? "64Gps" : "unknown");
79972a92df2SJoe Carnuccio if (vha->min_supported_speed) {
80072a92df2SJoe Carnuccio ha->min_supported_speed = mcp->mb[5] &
80172a92df2SJoe Carnuccio (BIT_0 | BIT_1 | BIT_2);
80292d4408eSSawan Chandak ql_dbg(ql_dbg_mbx, vha, 0x119c,
80372a92df2SJoe Carnuccio "min_supported_speed=%s.\n",
80472a92df2SJoe Carnuccio ha->min_supported_speed == 6 ? "64Gps" :
80572a92df2SJoe Carnuccio ha->min_supported_speed == 5 ? "32Gps" :
80672a92df2SJoe Carnuccio ha->min_supported_speed == 4 ? "16Gps" :
80772a92df2SJoe Carnuccio ha->min_supported_speed == 3 ? "8Gps" :
80872a92df2SJoe Carnuccio ha->min_supported_speed == 2 ? "4Gps" : "unknown");
80992d4408eSSawan Chandak }
81092d4408eSSawan Chandak }
81172a92df2SJoe Carnuccio
812d07b75baSQuinn Tran if (IS_QLA28XX(ha) && (mcp->mb[5] & EDIF_HW_SUPPORT)) {
813d07b75baSQuinn Tran ha->flags.edif_hw = 1;
81444d01857SQuinn Tran ql_log(ql_log_info, vha, 0xffff,
815d07b75baSQuinn Tran "%s: edif HW\n", __func__);
81644d01857SQuinn Tran }
81744d01857SQuinn Tran
81872a92df2SJoe Carnuccio done:
8191f4c7c38SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
82072a92df2SJoe Carnuccio "Done %s.\n", __func__);
8211da177e4SLinus Torvalds
8221da177e4SLinus Torvalds return rval;
8231da177e4SLinus Torvalds }
8241da177e4SLinus Torvalds
8251da177e4SLinus Torvalds /*
826b0d6cabdSHimanshu Madhani * qla_get_exlogin_status
827b0d6cabdSHimanshu Madhani * Get extended login status
828b0d6cabdSHimanshu Madhani * uses the memory offload control/status Mailbox
829b0d6cabdSHimanshu Madhani *
830b0d6cabdSHimanshu Madhani * Input:
831b0d6cabdSHimanshu Madhani * ha: adapter state pointer.
832b0d6cabdSHimanshu Madhani * fwopt: firmware options
833b0d6cabdSHimanshu Madhani *
834b0d6cabdSHimanshu Madhani * Returns:
835b0d6cabdSHimanshu Madhani * qla2x00 local function status
836b0d6cabdSHimanshu Madhani *
837b0d6cabdSHimanshu Madhani * Context:
838b0d6cabdSHimanshu Madhani * Kernel context.
839b0d6cabdSHimanshu Madhani */
840b0d6cabdSHimanshu Madhani #define FETCH_XLOGINS_STAT 0x8
841b0d6cabdSHimanshu Madhani int
qla_get_exlogin_status(scsi_qla_host_t * vha,uint16_t * buf_sz,uint16_t * ex_logins_cnt)842b0d6cabdSHimanshu Madhani qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
843b0d6cabdSHimanshu Madhani uint16_t *ex_logins_cnt)
844b0d6cabdSHimanshu Madhani {
845b0d6cabdSHimanshu Madhani int rval;
846b0d6cabdSHimanshu Madhani mbx_cmd_t mc;
847b0d6cabdSHimanshu Madhani mbx_cmd_t *mcp = &mc;
848b0d6cabdSHimanshu Madhani
849b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
850b0d6cabdSHimanshu Madhani "Entered %s\n", __func__);
851b0d6cabdSHimanshu Madhani
852b0d6cabdSHimanshu Madhani memset(mcp->mb, 0 , sizeof(mcp->mb));
853b0d6cabdSHimanshu Madhani mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
854b0d6cabdSHimanshu Madhani mcp->mb[1] = FETCH_XLOGINS_STAT;
855b0d6cabdSHimanshu Madhani mcp->out_mb = MBX_1|MBX_0;
856b0d6cabdSHimanshu Madhani mcp->in_mb = MBX_10|MBX_4|MBX_0;
857b0d6cabdSHimanshu Madhani mcp->tov = MBX_TOV_SECONDS;
858b0d6cabdSHimanshu Madhani mcp->flags = 0;
859b0d6cabdSHimanshu Madhani
860b0d6cabdSHimanshu Madhani rval = qla2x00_mailbox_command(vha, mcp);
861b0d6cabdSHimanshu Madhani if (rval != QLA_SUCCESS) {
862b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
863b0d6cabdSHimanshu Madhani } else {
864b0d6cabdSHimanshu Madhani *buf_sz = mcp->mb[4];
865b0d6cabdSHimanshu Madhani *ex_logins_cnt = mcp->mb[10];
866b0d6cabdSHimanshu Madhani
867b0d6cabdSHimanshu Madhani ql_log(ql_log_info, vha, 0x1190,
868b0d6cabdSHimanshu Madhani "buffer size 0x%x, exchange login count=%d\n",
869b0d6cabdSHimanshu Madhani mcp->mb[4], mcp->mb[10]);
870b0d6cabdSHimanshu Madhani
871b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
872b0d6cabdSHimanshu Madhani "Done %s.\n", __func__);
873b0d6cabdSHimanshu Madhani }
874b0d6cabdSHimanshu Madhani
875b0d6cabdSHimanshu Madhani return rval;
876b0d6cabdSHimanshu Madhani }
877b0d6cabdSHimanshu Madhani
878b0d6cabdSHimanshu Madhani /*
879b0d6cabdSHimanshu Madhani * qla_set_exlogin_mem_cfg
880b0d6cabdSHimanshu Madhani * set extended login memory configuration
881b0d6cabdSHimanshu Madhani * Mbx needs to be issues before init_cb is set
882b0d6cabdSHimanshu Madhani *
883b0d6cabdSHimanshu Madhani * Input:
884b0d6cabdSHimanshu Madhani * ha: adapter state pointer.
885b0d6cabdSHimanshu Madhani * buffer: buffer pointer
886b0d6cabdSHimanshu Madhani * phys_addr: physical address of buffer
887b0d6cabdSHimanshu Madhani * size: size of buffer
888b0d6cabdSHimanshu Madhani * TARGET_QUEUE_LOCK must be released
889b0d6cabdSHimanshu Madhani * ADAPTER_STATE_LOCK must be release
890b0d6cabdSHimanshu Madhani *
891b0d6cabdSHimanshu Madhani * Returns:
892b0d6cabdSHimanshu Madhani * qla2x00 local funxtion status code.
893b0d6cabdSHimanshu Madhani *
894b0d6cabdSHimanshu Madhani * Context:
895b0d6cabdSHimanshu Madhani * Kernel context.
896b0d6cabdSHimanshu Madhani */
897d38cb849SQuinn Tran #define CONFIG_XLOGINS_MEM 0x9
898b0d6cabdSHimanshu Madhani int
qla_set_exlogin_mem_cfg(scsi_qla_host_t * vha,dma_addr_t phys_addr)899b0d6cabdSHimanshu Madhani qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
900b0d6cabdSHimanshu Madhani {
901b0d6cabdSHimanshu Madhani int rval;
902b0d6cabdSHimanshu Madhani mbx_cmd_t mc;
903b0d6cabdSHimanshu Madhani mbx_cmd_t *mcp = &mc;
904b0d6cabdSHimanshu Madhani struct qla_hw_data *ha = vha->hw;
905b0d6cabdSHimanshu Madhani
906b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
907b0d6cabdSHimanshu Madhani "Entered %s.\n", __func__);
908b0d6cabdSHimanshu Madhani
909b0d6cabdSHimanshu Madhani memset(mcp->mb, 0 , sizeof(mcp->mb));
910b0d6cabdSHimanshu Madhani mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
911b0d6cabdSHimanshu Madhani mcp->mb[1] = CONFIG_XLOGINS_MEM;
912b0d6cabdSHimanshu Madhani mcp->mb[2] = MSW(phys_addr);
913b0d6cabdSHimanshu Madhani mcp->mb[3] = LSW(phys_addr);
914b0d6cabdSHimanshu Madhani mcp->mb[6] = MSW(MSD(phys_addr));
915b0d6cabdSHimanshu Madhani mcp->mb[7] = LSW(MSD(phys_addr));
916b0d6cabdSHimanshu Madhani mcp->mb[8] = MSW(ha->exlogin_size);
917b0d6cabdSHimanshu Madhani mcp->mb[9] = LSW(ha->exlogin_size);
918b0d6cabdSHimanshu Madhani mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
919b0d6cabdSHimanshu Madhani mcp->in_mb = MBX_11|MBX_0;
920b0d6cabdSHimanshu Madhani mcp->tov = MBX_TOV_SECONDS;
921b0d6cabdSHimanshu Madhani mcp->flags = 0;
922b0d6cabdSHimanshu Madhani rval = qla2x00_mailbox_command(vha, mcp);
923b0d6cabdSHimanshu Madhani if (rval != QLA_SUCCESS) {
924d38cb849SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x111b,
925d38cb849SQuinn Tran "EXlogin Failed=%x. MB0=%x MB11=%x\n",
926d38cb849SQuinn Tran rval, mcp->mb[0], mcp->mb[11]);
927b0d6cabdSHimanshu Madhani } else {
928b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
929b0d6cabdSHimanshu Madhani "Done %s.\n", __func__);
930b0d6cabdSHimanshu Madhani }
931b0d6cabdSHimanshu Madhani
932b0d6cabdSHimanshu Madhani return rval;
933b0d6cabdSHimanshu Madhani }
934b0d6cabdSHimanshu Madhani
935b0d6cabdSHimanshu Madhani /*
9362f56a7f1SHimanshu Madhani * qla_get_exchoffld_status
9372f56a7f1SHimanshu Madhani * Get exchange offload status
9382f56a7f1SHimanshu Madhani * uses the memory offload control/status Mailbox
9392f56a7f1SHimanshu Madhani *
9402f56a7f1SHimanshu Madhani * Input:
9412f56a7f1SHimanshu Madhani * ha: adapter state pointer.
9422f56a7f1SHimanshu Madhani * fwopt: firmware options
9432f56a7f1SHimanshu Madhani *
9442f56a7f1SHimanshu Madhani * Returns:
9452f56a7f1SHimanshu Madhani * qla2x00 local function status
9462f56a7f1SHimanshu Madhani *
9472f56a7f1SHimanshu Madhani * Context:
9482f56a7f1SHimanshu Madhani * Kernel context.
9492f56a7f1SHimanshu Madhani */
9502f56a7f1SHimanshu Madhani #define FETCH_XCHOFFLD_STAT 0x2
9512f56a7f1SHimanshu Madhani int
qla_get_exchoffld_status(scsi_qla_host_t * vha,uint16_t * buf_sz,uint16_t * ex_logins_cnt)9522f56a7f1SHimanshu Madhani qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
9532f56a7f1SHimanshu Madhani uint16_t *ex_logins_cnt)
9542f56a7f1SHimanshu Madhani {
9552f56a7f1SHimanshu Madhani int rval;
9562f56a7f1SHimanshu Madhani mbx_cmd_t mc;
9572f56a7f1SHimanshu Madhani mbx_cmd_t *mcp = &mc;
9582f56a7f1SHimanshu Madhani
9592f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
9602f56a7f1SHimanshu Madhani "Entered %s\n", __func__);
9612f56a7f1SHimanshu Madhani
9622f56a7f1SHimanshu Madhani memset(mcp->mb, 0 , sizeof(mcp->mb));
9632f56a7f1SHimanshu Madhani mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
9642f56a7f1SHimanshu Madhani mcp->mb[1] = FETCH_XCHOFFLD_STAT;
9652f56a7f1SHimanshu Madhani mcp->out_mb = MBX_1|MBX_0;
9662f56a7f1SHimanshu Madhani mcp->in_mb = MBX_10|MBX_4|MBX_0;
9672f56a7f1SHimanshu Madhani mcp->tov = MBX_TOV_SECONDS;
9682f56a7f1SHimanshu Madhani mcp->flags = 0;
9692f56a7f1SHimanshu Madhani
9702f56a7f1SHimanshu Madhani rval = qla2x00_mailbox_command(vha, mcp);
9712f56a7f1SHimanshu Madhani if (rval != QLA_SUCCESS) {
9722f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
9732f56a7f1SHimanshu Madhani } else {
9742f56a7f1SHimanshu Madhani *buf_sz = mcp->mb[4];
9752f56a7f1SHimanshu Madhani *ex_logins_cnt = mcp->mb[10];
9762f56a7f1SHimanshu Madhani
9772f56a7f1SHimanshu Madhani ql_log(ql_log_info, vha, 0x118e,
9782f56a7f1SHimanshu Madhani "buffer size 0x%x, exchange offload count=%d\n",
9792f56a7f1SHimanshu Madhani mcp->mb[4], mcp->mb[10]);
9802f56a7f1SHimanshu Madhani
9812f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
9822f56a7f1SHimanshu Madhani "Done %s.\n", __func__);
9832f56a7f1SHimanshu Madhani }
9842f56a7f1SHimanshu Madhani
9852f56a7f1SHimanshu Madhani return rval;
9862f56a7f1SHimanshu Madhani }
9872f56a7f1SHimanshu Madhani
9882f56a7f1SHimanshu Madhani /*
9892f56a7f1SHimanshu Madhani * qla_set_exchoffld_mem_cfg
9902f56a7f1SHimanshu Madhani * Set exchange offload memory configuration
9912f56a7f1SHimanshu Madhani * Mbx needs to be issues before init_cb is set
9922f56a7f1SHimanshu Madhani *
9932f56a7f1SHimanshu Madhani * Input:
9942f56a7f1SHimanshu Madhani * ha: adapter state pointer.
9952f56a7f1SHimanshu Madhani * buffer: buffer pointer
9962f56a7f1SHimanshu Madhani * phys_addr: physical address of buffer
9972f56a7f1SHimanshu Madhani * size: size of buffer
9982f56a7f1SHimanshu Madhani * TARGET_QUEUE_LOCK must be released
9992f56a7f1SHimanshu Madhani * ADAPTER_STATE_LOCK must be release
10002f56a7f1SHimanshu Madhani *
10012f56a7f1SHimanshu Madhani * Returns:
10022f56a7f1SHimanshu Madhani * qla2x00 local funxtion status code.
10032f56a7f1SHimanshu Madhani *
10042f56a7f1SHimanshu Madhani * Context:
10052f56a7f1SHimanshu Madhani * Kernel context.
10062f56a7f1SHimanshu Madhani */
10072f56a7f1SHimanshu Madhani #define CONFIG_XCHOFFLD_MEM 0x3
10082f56a7f1SHimanshu Madhani int
qla_set_exchoffld_mem_cfg(scsi_qla_host_t * vha)100999e1b683SQuinn Tran qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)
10102f56a7f1SHimanshu Madhani {
10112f56a7f1SHimanshu Madhani int rval;
10122f56a7f1SHimanshu Madhani mbx_cmd_t mc;
10132f56a7f1SHimanshu Madhani mbx_cmd_t *mcp = &mc;
10142f56a7f1SHimanshu Madhani struct qla_hw_data *ha = vha->hw;
10152f56a7f1SHimanshu Madhani
10162f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
10172f56a7f1SHimanshu Madhani "Entered %s.\n", __func__);
10182f56a7f1SHimanshu Madhani
10192f56a7f1SHimanshu Madhani memset(mcp->mb, 0 , sizeof(mcp->mb));
10202f56a7f1SHimanshu Madhani mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
10212f56a7f1SHimanshu Madhani mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
102299e1b683SQuinn Tran mcp->mb[2] = MSW(ha->exchoffld_buf_dma);
102399e1b683SQuinn Tran mcp->mb[3] = LSW(ha->exchoffld_buf_dma);
102499e1b683SQuinn Tran mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));
102599e1b683SQuinn Tran mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));
102699e1b683SQuinn Tran mcp->mb[8] = MSW(ha->exchoffld_size);
102799e1b683SQuinn Tran mcp->mb[9] = LSW(ha->exchoffld_size);
10282f56a7f1SHimanshu Madhani mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
10292f56a7f1SHimanshu Madhani mcp->in_mb = MBX_11|MBX_0;
10302f56a7f1SHimanshu Madhani mcp->tov = MBX_TOV_SECONDS;
10312f56a7f1SHimanshu Madhani mcp->flags = 0;
10322f56a7f1SHimanshu Madhani rval = qla2x00_mailbox_command(vha, mcp);
10332f56a7f1SHimanshu Madhani if (rval != QLA_SUCCESS) {
10342f56a7f1SHimanshu Madhani /*EMPTY*/
10352f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
10362f56a7f1SHimanshu Madhani } else {
10372f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
10382f56a7f1SHimanshu Madhani "Done %s.\n", __func__);
10392f56a7f1SHimanshu Madhani }
10402f56a7f1SHimanshu Madhani
10412f56a7f1SHimanshu Madhani return rval;
10422f56a7f1SHimanshu Madhani }
10432f56a7f1SHimanshu Madhani
10442f56a7f1SHimanshu Madhani /*
10451da177e4SLinus Torvalds * qla2x00_get_fw_version
10461da177e4SLinus Torvalds * Get firmware version.
10471da177e4SLinus Torvalds *
10481da177e4SLinus Torvalds * Input:
10491da177e4SLinus Torvalds * ha: adapter state pointer.
10501da177e4SLinus Torvalds * major: pointer for major number.
10511da177e4SLinus Torvalds * minor: pointer for minor number.
10521da177e4SLinus Torvalds * subminor: pointer for subminor number.
10531da177e4SLinus Torvalds *
10541da177e4SLinus Torvalds * Returns:
10551da177e4SLinus Torvalds * qla2x00 local function return status code.
10561da177e4SLinus Torvalds *
10571da177e4SLinus Torvalds * Context:
10581da177e4SLinus Torvalds * Kernel context.
10591da177e4SLinus Torvalds */
1060ca9e9c3eSAndrew Vasquez int
qla2x00_get_fw_version(scsi_qla_host_t * vha)10616246b8a1SGiridhar Malavali qla2x00_get_fw_version(scsi_qla_host_t *vha)
10621da177e4SLinus Torvalds {
10631da177e4SLinus Torvalds int rval;
10641da177e4SLinus Torvalds mbx_cmd_t mc;
10651da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
10666246b8a1SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
10671da177e4SLinus Torvalds
10685f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
10695f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
10701da177e4SLinus Torvalds
10711da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
10721da177e4SLinus Torvalds mcp->out_mb = MBX_0;
10731da177e4SLinus Torvalds mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
10747ec0effdSAtul Deshmukh if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
107555a96158SAndrew Vasquez mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
1076fb0effeeSSaurav Kashyap if (IS_FWI2_CAPABLE(ha))
10776246b8a1SGiridhar Malavali mcp->in_mb |= MBX_17|MBX_16|MBX_15;
1078ecc89f25SJoe Carnuccio if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
1079ad1ef177SJoe Carnuccio mcp->in_mb |=
1080ad1ef177SJoe Carnuccio MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
10812a3192a3SJoe Carnuccio MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7;
108203aa868cSSawan Chandak
10831da177e4SLinus Torvalds mcp->flags = 0;
1084b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
10857b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
1086ca9e9c3eSAndrew Vasquez if (rval != QLA_SUCCESS)
1087ca9e9c3eSAndrew Vasquez goto failed;
10881da177e4SLinus Torvalds
10891da177e4SLinus Torvalds /* Return mailbox data. */
10906246b8a1SGiridhar Malavali ha->fw_major_version = mcp->mb[1];
10916246b8a1SGiridhar Malavali ha->fw_minor_version = mcp->mb[2];
10926246b8a1SGiridhar Malavali ha->fw_subminor_version = mcp->mb[3];
10936246b8a1SGiridhar Malavali ha->fw_attributes = mcp->mb[6];
10947b867cf7SAnirban Chakraborty if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
10956246b8a1SGiridhar Malavali ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
10961da177e4SLinus Torvalds else
10976246b8a1SGiridhar Malavali ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
109803aa868cSSawan Chandak
10997ec0effdSAtul Deshmukh if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
11006246b8a1SGiridhar Malavali ha->mpi_version[0] = mcp->mb[10] & 0xff;
11016246b8a1SGiridhar Malavali ha->mpi_version[1] = mcp->mb[11] >> 8;
11026246b8a1SGiridhar Malavali ha->mpi_version[2] = mcp->mb[11] & 0xff;
11036246b8a1SGiridhar Malavali ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
11046246b8a1SGiridhar Malavali ha->phy_version[0] = mcp->mb[8] & 0xff;
11056246b8a1SGiridhar Malavali ha->phy_version[1] = mcp->mb[9] >> 8;
11066246b8a1SGiridhar Malavali ha->phy_version[2] = mcp->mb[9] & 0xff;
11073a03eb79SAndrew Vasquez }
110803aa868cSSawan Chandak
110981178772SSaurav Kashyap if (IS_FWI2_CAPABLE(ha)) {
11106246b8a1SGiridhar Malavali ha->fw_attributes_h = mcp->mb[15];
11116246b8a1SGiridhar Malavali ha->fw_attributes_ext[0] = mcp->mb[16];
11126246b8a1SGiridhar Malavali ha->fw_attributes_ext[1] = mcp->mb[17];
11135f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
11146246b8a1SGiridhar Malavali "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
11156246b8a1SGiridhar Malavali __func__, mcp->mb[15], mcp->mb[6]);
11165f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
111781178772SSaurav Kashyap "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
111881178772SSaurav Kashyap __func__, mcp->mb[17], mcp->mb[16]);
11192f56a7f1SHimanshu Madhani
1120b0d6cabdSHimanshu Madhani if (ha->fw_attributes_h & 0x4)
1121b0d6cabdSHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
1122b0d6cabdSHimanshu Madhani "%s: Firmware supports Extended Login 0x%x\n",
1123b0d6cabdSHimanshu Madhani __func__, ha->fw_attributes_h);
11242f56a7f1SHimanshu Madhani
11252f56a7f1SHimanshu Madhani if (ha->fw_attributes_h & 0x8)
11262f56a7f1SHimanshu Madhani ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
11272f56a7f1SHimanshu Madhani "%s: Firmware supports Exchange Offload 0x%x\n",
11282f56a7f1SHimanshu Madhani __func__, ha->fw_attributes_h);
1129e84067d7SDuane Grigsby
1130e84067d7SDuane Grigsby /*
1131deeae7a6SDuane Grigsby * FW supports nvme and driver load parameter requested nvme.
1132deeae7a6SDuane Grigsby * BIT 26 of fw_attributes indicates NVMe support.
1133e84067d7SDuane Grigsby */
1134171e4909SGiridhar Malavali if ((ha->fw_attributes_h &
1135171e4909SGiridhar Malavali (FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) &&
1136171e4909SGiridhar Malavali ql2xnvmeenable) {
113703aaa89fSDarren Trapp if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST)
113803aaa89fSDarren Trapp vha->flags.nvme_first_burst = 1;
113903aaa89fSDarren Trapp
1140e84067d7SDuane Grigsby vha->flags.nvme_enabled = 1;
11411cbc0efcSDarren Trapp ql_log(ql_log_info, vha, 0xd302,
11421cbc0efcSDarren Trapp "%s: FC-NVMe is Enabled (0x%x)\n",
11431cbc0efcSDarren Trapp __func__, ha->fw_attributes_h);
11441cbc0efcSDarren Trapp }
1145cf3c54fbSSaurav Kashyap
1146cf3c54fbSSaurav Kashyap /* BIT_13 of Extended FW Attributes informs about NVMe2 support */
1147cf3c54fbSSaurav Kashyap if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) {
1148cf3c54fbSSaurav Kashyap ql_log(ql_log_info, vha, 0xd302,
1149cf3c54fbSSaurav Kashyap "Firmware supports NVMe2 0x%x\n",
1150cf3c54fbSSaurav Kashyap ha->fw_attributes_ext[0]);
1151cf3c54fbSSaurav Kashyap vha->flags.nvme2_enabled = 1;
1152cf3c54fbSSaurav Kashyap }
1153d07b75baSQuinn Tran
1154d07b75baSQuinn Tran if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable &&
1155d07b75baSQuinn Tran (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) {
1156d07b75baSQuinn Tran ha->flags.edif_enabled = 1;
11574de067e5SQuinn Tran ql_log(ql_log_info, vha, 0xffff,
1158d07b75baSQuinn Tran "%s: edif is enabled\n", __func__);
1159d07b75baSQuinn Tran }
11606246b8a1SGiridhar Malavali }
116103aa868cSSawan Chandak
1162ecc89f25SJoe Carnuccio if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
11632a3192a3SJoe Carnuccio ha->serdes_version[0] = mcp->mb[7] & 0xff;
11642a3192a3SJoe Carnuccio ha->serdes_version[1] = mcp->mb[8] >> 8;
11652a3192a3SJoe Carnuccio ha->serdes_version[2] = mcp->mb[8] & 0xff;
116603aa868cSSawan Chandak ha->mpi_version[0] = mcp->mb[10] & 0xff;
116703aa868cSSawan Chandak ha->mpi_version[1] = mcp->mb[11] >> 8;
116803aa868cSSawan Chandak ha->mpi_version[2] = mcp->mb[11] & 0xff;
116903aa868cSSawan Chandak ha->pep_version[0] = mcp->mb[13] & 0xff;
117003aa868cSSawan Chandak ha->pep_version[1] = mcp->mb[14] >> 8;
117103aa868cSSawan Chandak ha->pep_version[2] = mcp->mb[14] & 0xff;
1172f73cb695SChad Dupuis ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
1173f73cb695SChad Dupuis ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
1174ad1ef177SJoe Carnuccio ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
1175ad1ef177SJoe Carnuccio ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
11763f006ac3SMichael Hernandez if (IS_QLA28XX(ha)) {
11774ba836f6SMichael Hernandez if (mcp->mb[16] & BIT_10)
11783f006ac3SMichael Hernandez ha->flags.secure_fw = 1;
11794ba836f6SMichael Hernandez
11804ba836f6SMichael Hernandez ql_log(ql_log_info, vha, 0xffff,
11814ba836f6SMichael Hernandez "Secure Flash Update in FW: %s\n",
11824ba836f6SMichael Hernandez (ha->flags.secure_fw) ? "Supported" :
11834ba836f6SMichael Hernandez "Not Supported");
11843f006ac3SMichael Hernandez }
11859f2475feSShyam Sundar
11869f2475feSShyam Sundar if (ha->flags.scm_supported_a &&
11879f2475feSShyam Sundar (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
11889f2475feSShyam Sundar ha->flags.scm_supported_f = 1;
11898a78dd6eSArun Easi ha->sf_init_cb->flags |= cpu_to_le16(BIT_13);
11909f2475feSShyam Sundar }
11919f2475feSShyam Sundar ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
11929f2475feSShyam Sundar (ha->flags.scm_supported_f) ? "Supported" :
11939f2475feSShyam Sundar "Not Supported");
1194cf3c54fbSSaurav Kashyap
1195cf3c54fbSSaurav Kashyap if (vha->flags.nvme2_enabled) {
1196cf3c54fbSSaurav Kashyap /* set BIT_15 of special feature control block for SLER */
11978a78dd6eSArun Easi ha->sf_init_cb->flags |= cpu_to_le16(BIT_15);
1198cf3c54fbSSaurav Kashyap /* set BIT_14 of special feature control block for PI CTRL*/
11998a78dd6eSArun Easi ha->sf_init_cb->flags |= cpu_to_le16(BIT_14);
1200cf3c54fbSSaurav Kashyap }
1201f73cb695SChad Dupuis }
12026246b8a1SGiridhar Malavali
1203ca9e9c3eSAndrew Vasquez failed:
12041da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
12051da177e4SLinus Torvalds /*EMPTY*/
12067c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
12071da177e4SLinus Torvalds } else {
12081da177e4SLinus Torvalds /*EMPTY*/
12095f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
12105f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
12111da177e4SLinus Torvalds }
1212ca9e9c3eSAndrew Vasquez return rval;
12131da177e4SLinus Torvalds }
12141da177e4SLinus Torvalds
12151da177e4SLinus Torvalds /*
12161da177e4SLinus Torvalds * qla2x00_get_fw_options
12171da177e4SLinus Torvalds * Set firmware options.
12181da177e4SLinus Torvalds *
12191da177e4SLinus Torvalds * Input:
12201da177e4SLinus Torvalds * ha = adapter block pointer.
12211da177e4SLinus Torvalds * fwopt = pointer for firmware options.
12221da177e4SLinus Torvalds *
12231da177e4SLinus Torvalds * Returns:
12241da177e4SLinus Torvalds * qla2x00 local function return status code.
12251da177e4SLinus Torvalds *
12261da177e4SLinus Torvalds * Context:
12271da177e4SLinus Torvalds * Kernel context.
12281da177e4SLinus Torvalds */
12291da177e4SLinus Torvalds int
qla2x00_get_fw_options(scsi_qla_host_t * vha,uint16_t * fwopts)12307b867cf7SAnirban Chakraborty qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
12311da177e4SLinus Torvalds {
12321da177e4SLinus Torvalds int rval;
12331da177e4SLinus Torvalds mbx_cmd_t mc;
12341da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
12351da177e4SLinus Torvalds
12365f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
12375f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
12381da177e4SLinus Torvalds
12391da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
12401da177e4SLinus Torvalds mcp->out_mb = MBX_0;
12411da177e4SLinus Torvalds mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1242b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
12431da177e4SLinus Torvalds mcp->flags = 0;
12447b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
12451da177e4SLinus Torvalds
12461da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
12471da177e4SLinus Torvalds /*EMPTY*/
12487c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
12491da177e4SLinus Torvalds } else {
12501c7c6357SAndrew Vasquez fwopts[0] = mcp->mb[0];
12511da177e4SLinus Torvalds fwopts[1] = mcp->mb[1];
12521da177e4SLinus Torvalds fwopts[2] = mcp->mb[2];
12531da177e4SLinus Torvalds fwopts[3] = mcp->mb[3];
12541da177e4SLinus Torvalds
12555f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
12565f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
12571da177e4SLinus Torvalds }
12581da177e4SLinus Torvalds
12591da177e4SLinus Torvalds return rval;
12601da177e4SLinus Torvalds }
12611da177e4SLinus Torvalds
12621da177e4SLinus Torvalds
12631da177e4SLinus Torvalds /*
12641da177e4SLinus Torvalds * qla2x00_set_fw_options
12651da177e4SLinus Torvalds * Set firmware options.
12661da177e4SLinus Torvalds *
12671da177e4SLinus Torvalds * Input:
12681da177e4SLinus Torvalds * ha = adapter block pointer.
12691da177e4SLinus Torvalds * fwopt = pointer for firmware options.
12701da177e4SLinus Torvalds *
12711da177e4SLinus Torvalds * Returns:
12721da177e4SLinus Torvalds * qla2x00 local function return status code.
12731da177e4SLinus Torvalds *
12741da177e4SLinus Torvalds * Context:
12751da177e4SLinus Torvalds * Kernel context.
12761da177e4SLinus Torvalds */
12771da177e4SLinus Torvalds int
qla2x00_set_fw_options(scsi_qla_host_t * vha,uint16_t * fwopts)12787b867cf7SAnirban Chakraborty qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
12791da177e4SLinus Torvalds {
12801da177e4SLinus Torvalds int rval;
12811da177e4SLinus Torvalds mbx_cmd_t mc;
12821da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
12831da177e4SLinus Torvalds
12845f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
12855f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
12861da177e4SLinus Torvalds
12871da177e4SLinus Torvalds mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
12881da177e4SLinus Torvalds mcp->mb[1] = fwopts[1];
12891da177e4SLinus Torvalds mcp->mb[2] = fwopts[2];
12901da177e4SLinus Torvalds mcp->mb[3] = fwopts[3];
12911c7c6357SAndrew Vasquez mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
12921c7c6357SAndrew Vasquez mcp->in_mb = MBX_0;
12937b867cf7SAnirban Chakraborty if (IS_FWI2_CAPABLE(vha->hw)) {
12941c7c6357SAndrew Vasquez mcp->in_mb |= MBX_1;
12952da52737SQuinn Tran mcp->mb[10] = fwopts[10];
12962da52737SQuinn Tran mcp->out_mb |= MBX_10;
12971c7c6357SAndrew Vasquez } else {
12981da177e4SLinus Torvalds mcp->mb[10] = fwopts[10];
12991da177e4SLinus Torvalds mcp->mb[11] = fwopts[11];
13001da177e4SLinus Torvalds mcp->mb[12] = 0; /* Undocumented, but used */
13011c7c6357SAndrew Vasquez mcp->out_mb |= MBX_12|MBX_11|MBX_10;
13021c7c6357SAndrew Vasquez }
1303b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
13041da177e4SLinus Torvalds mcp->flags = 0;
13057b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
13061da177e4SLinus Torvalds
13071c7c6357SAndrew Vasquez fwopts[0] = mcp->mb[0];
13081c7c6357SAndrew Vasquez
13091da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
13101da177e4SLinus Torvalds /*EMPTY*/
13117c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1030,
13127c3df132SSaurav Kashyap "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
13131da177e4SLinus Torvalds } else {
13141da177e4SLinus Torvalds /*EMPTY*/
13155f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
13165f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
13171da177e4SLinus Torvalds }
13181da177e4SLinus Torvalds
13191da177e4SLinus Torvalds return rval;
13201da177e4SLinus Torvalds }
13211da177e4SLinus Torvalds
13221da177e4SLinus Torvalds /*
13231da177e4SLinus Torvalds * qla2x00_mbx_reg_test
13241da177e4SLinus Torvalds * Mailbox register wrap test.
13251da177e4SLinus Torvalds *
13261da177e4SLinus Torvalds * Input:
13271da177e4SLinus Torvalds * ha = adapter block pointer.
13281da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
13291da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
13301da177e4SLinus Torvalds *
13311da177e4SLinus Torvalds * Returns:
13321da177e4SLinus Torvalds * qla2x00 local function return status code.
13331da177e4SLinus Torvalds *
13341da177e4SLinus Torvalds * Context:
13351da177e4SLinus Torvalds * Kernel context.
13361da177e4SLinus Torvalds */
13371da177e4SLinus Torvalds int
qla2x00_mbx_reg_test(scsi_qla_host_t * vha)13387b867cf7SAnirban Chakraborty qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
13391da177e4SLinus Torvalds {
13401da177e4SLinus Torvalds int rval;
13411da177e4SLinus Torvalds mbx_cmd_t mc;
13421da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
13431da177e4SLinus Torvalds
13445f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
13455f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
13461da177e4SLinus Torvalds
13471da177e4SLinus Torvalds mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
13481da177e4SLinus Torvalds mcp->mb[1] = 0xAAAA;
13491da177e4SLinus Torvalds mcp->mb[2] = 0x5555;
13501da177e4SLinus Torvalds mcp->mb[3] = 0xAA55;
13511da177e4SLinus Torvalds mcp->mb[4] = 0x55AA;
13521da177e4SLinus Torvalds mcp->mb[5] = 0xA5A5;
13531da177e4SLinus Torvalds mcp->mb[6] = 0x5A5A;
13541da177e4SLinus Torvalds mcp->mb[7] = 0x2525;
13551da177e4SLinus Torvalds mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
13561da177e4SLinus Torvalds mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1357b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
13581da177e4SLinus Torvalds mcp->flags = 0;
13597b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
13601da177e4SLinus Torvalds
13611da177e4SLinus Torvalds if (rval == QLA_SUCCESS) {
13621da177e4SLinus Torvalds if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
13631da177e4SLinus Torvalds mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
13641da177e4SLinus Torvalds rval = QLA_FUNCTION_FAILED;
13651da177e4SLinus Torvalds if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
13661da177e4SLinus Torvalds mcp->mb[7] != 0x2525)
13671da177e4SLinus Torvalds rval = QLA_FUNCTION_FAILED;
13681da177e4SLinus Torvalds }
13691da177e4SLinus Torvalds
13701da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
13711da177e4SLinus Torvalds /*EMPTY*/
13727c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
1373dbf1f53cSSaurav Kashyap vha->hw_err_cnt++;
13741da177e4SLinus Torvalds } else {
13751da177e4SLinus Torvalds /*EMPTY*/
13765f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
13775f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
13781da177e4SLinus Torvalds }
13791da177e4SLinus Torvalds
13801da177e4SLinus Torvalds return rval;
13811da177e4SLinus Torvalds }
13821da177e4SLinus Torvalds
13831da177e4SLinus Torvalds /*
13841da177e4SLinus Torvalds * qla2x00_verify_checksum
13851da177e4SLinus Torvalds * Verify firmware checksum.
13861da177e4SLinus Torvalds *
13871da177e4SLinus Torvalds * Input:
13881da177e4SLinus Torvalds * ha = adapter block pointer.
13891da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
13901da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
13911da177e4SLinus Torvalds *
13921da177e4SLinus Torvalds * Returns:
13931da177e4SLinus Torvalds * qla2x00 local function return status code.
13941da177e4SLinus Torvalds *
13951da177e4SLinus Torvalds * Context:
13961da177e4SLinus Torvalds * Kernel context.
13971da177e4SLinus Torvalds */
13981da177e4SLinus Torvalds int
qla2x00_verify_checksum(scsi_qla_host_t * vha,uint32_t risc_addr)13997b867cf7SAnirban Chakraborty qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
14001da177e4SLinus Torvalds {
14011da177e4SLinus Torvalds int rval;
14021da177e4SLinus Torvalds mbx_cmd_t mc;
14031da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
14041da177e4SLinus Torvalds
14055f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
14065f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
14071da177e4SLinus Torvalds
14081da177e4SLinus Torvalds mcp->mb[0] = MBC_VERIFY_CHECKSUM;
14091c7c6357SAndrew Vasquez mcp->out_mb = MBX_0;
14101c7c6357SAndrew Vasquez mcp->in_mb = MBX_0;
14117b867cf7SAnirban Chakraborty if (IS_FWI2_CAPABLE(vha->hw)) {
14121c7c6357SAndrew Vasquez mcp->mb[1] = MSW(risc_addr);
14131c7c6357SAndrew Vasquez mcp->mb[2] = LSW(risc_addr);
14141c7c6357SAndrew Vasquez mcp->out_mb |= MBX_2|MBX_1;
14151c7c6357SAndrew Vasquez mcp->in_mb |= MBX_2|MBX_1;
14161c7c6357SAndrew Vasquez } else {
14171c7c6357SAndrew Vasquez mcp->mb[1] = LSW(risc_addr);
14181c7c6357SAndrew Vasquez mcp->out_mb |= MBX_1;
14191c7c6357SAndrew Vasquez mcp->in_mb |= MBX_1;
14201c7c6357SAndrew Vasquez }
14211c7c6357SAndrew Vasquez
1422b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
14231da177e4SLinus Torvalds mcp->flags = 0;
14247b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
14251da177e4SLinus Torvalds
14261da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
14277c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1036,
14287c3df132SSaurav Kashyap "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
14297c3df132SSaurav Kashyap (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
14301da177e4SLinus Torvalds } else {
14315f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
14325f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
14331da177e4SLinus Torvalds }
14341da177e4SLinus Torvalds
14351da177e4SLinus Torvalds return rval;
14361da177e4SLinus Torvalds }
14371da177e4SLinus Torvalds
14381da177e4SLinus Torvalds /*
14391da177e4SLinus Torvalds * qla2x00_issue_iocb
14401da177e4SLinus Torvalds * Issue IOCB using mailbox command
14411da177e4SLinus Torvalds *
14421da177e4SLinus Torvalds * Input:
14431da177e4SLinus Torvalds * ha = adapter state pointer.
14441da177e4SLinus Torvalds * buffer = buffer pointer.
14451da177e4SLinus Torvalds * phys_addr = physical address of buffer.
14461da177e4SLinus Torvalds * size = size of buffer.
14471da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
14481da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
14491da177e4SLinus Torvalds *
14501da177e4SLinus Torvalds * Returns:
14511da177e4SLinus Torvalds * qla2x00 local function return status code.
14521da177e4SLinus Torvalds *
14531da177e4SLinus Torvalds * Context:
14541da177e4SLinus Torvalds * Kernel context.
14551da177e4SLinus Torvalds */
14566e98016cSGiridhar Malavali int
qla2x00_issue_iocb_timeout(scsi_qla_host_t * vha,void * buffer,dma_addr_t phys_addr,size_t size,uint32_t tov)14577b867cf7SAnirban Chakraborty qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
14584d4df193SHarihara Kadayam dma_addr_t phys_addr, size_t size, uint32_t tov)
14591da177e4SLinus Torvalds {
14601da177e4SLinus Torvalds int rval;
14611da177e4SLinus Torvalds mbx_cmd_t mc;
14621da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
14631da177e4SLinus Torvalds
1464ab391abdSQuinn Tran if (!vha->hw->flags.fw_started)
1465345f574dSHimanshu Madhani return QLA_INVALID_COMMAND;
1466345f574dSHimanshu Madhani
14675f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
14685f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
14697c3df132SSaurav Kashyap
14701da177e4SLinus Torvalds mcp->mb[0] = MBC_IOCB_COMMAND_A64;
14711da177e4SLinus Torvalds mcp->mb[1] = 0;
1472818c7f87SJoe Carnuccio mcp->mb[2] = MSW(LSD(phys_addr));
1473818c7f87SJoe Carnuccio mcp->mb[3] = LSW(LSD(phys_addr));
14741da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(phys_addr));
14751da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(phys_addr));
14761da177e4SLinus Torvalds mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1477818c7f87SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
14784d4df193SHarihara Kadayam mcp->tov = tov;
14791da177e4SLinus Torvalds mcp->flags = 0;
14807b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
14811da177e4SLinus Torvalds
14821da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
14831da177e4SLinus Torvalds /*EMPTY*/
14847c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
14851da177e4SLinus Torvalds } else {
1486818c7f87SJoe Carnuccio sts_entry_t *sts_entry = buffer;
14878c958a99SAndrew Vasquez
14888c958a99SAndrew Vasquez /* Mask reserved bits. */
14898c958a99SAndrew Vasquez sts_entry->entry_status &=
14907b867cf7SAnirban Chakraborty IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
14915f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1492818c7f87SJoe Carnuccio "Done %s (status=%x).\n", __func__,
1493818c7f87SJoe Carnuccio sts_entry->entry_status);
14941da177e4SLinus Torvalds }
14951da177e4SLinus Torvalds
14961da177e4SLinus Torvalds return rval;
14971da177e4SLinus Torvalds }
14981da177e4SLinus Torvalds
14994d4df193SHarihara Kadayam int
qla2x00_issue_iocb(scsi_qla_host_t * vha,void * buffer,dma_addr_t phys_addr,size_t size)15007b867cf7SAnirban Chakraborty qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
15014d4df193SHarihara Kadayam size_t size)
15024d4df193SHarihara Kadayam {
15037b867cf7SAnirban Chakraborty return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
15044d4df193SHarihara Kadayam MBX_TOV_SECONDS);
15054d4df193SHarihara Kadayam }
15064d4df193SHarihara Kadayam
15071da177e4SLinus Torvalds /*
15081da177e4SLinus Torvalds * qla2x00_abort_command
15091da177e4SLinus Torvalds * Abort command aborts a specified IOCB.
15101da177e4SLinus Torvalds *
15111da177e4SLinus Torvalds * Input:
15121da177e4SLinus Torvalds * ha = adapter block pointer.
15131da177e4SLinus Torvalds * sp = SB structure pointer.
15141da177e4SLinus Torvalds *
15151da177e4SLinus Torvalds * Returns:
15161da177e4SLinus Torvalds * qla2x00 local function return status code.
15171da177e4SLinus Torvalds *
15181da177e4SLinus Torvalds * Context:
15191da177e4SLinus Torvalds * Kernel context.
15201da177e4SLinus Torvalds */
15211da177e4SLinus Torvalds int
qla2x00_abort_command(srb_t * sp)15222afa19a9SAnirban Chakraborty qla2x00_abort_command(srb_t *sp)
15231da177e4SLinus Torvalds {
15241da177e4SLinus Torvalds unsigned long flags = 0;
15251da177e4SLinus Torvalds int rval;
152673208dfdSAnirban Chakraborty uint32_t handle = 0;
15271da177e4SLinus Torvalds mbx_cmd_t mc;
15281da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
15292afa19a9SAnirban Chakraborty fc_port_t *fcport = sp->fcport;
15302afa19a9SAnirban Chakraborty scsi_qla_host_t *vha = fcport->vha;
15317b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
1532d7459527SMichael Hernandez struct req_que *req;
15339ba56b95SGiridhar Malavali struct scsi_cmnd *cmd = GET_CMD_SP(sp);
15341da177e4SLinus Torvalds
15355f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
15365f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
15371da177e4SLinus Torvalds
1538345f574dSHimanshu Madhani if (sp->qpair)
1539d7459527SMichael Hernandez req = sp->qpair->req;
1540d7459527SMichael Hernandez else
1541d7459527SMichael Hernandez req = vha->req;
1542d7459527SMichael Hernandez
1543c9c5ced9SAndrew Vasquez spin_lock_irqsave(&ha->hardware_lock, flags);
15448d93f550SChad Dupuis for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
15457b867cf7SAnirban Chakraborty if (req->outstanding_cmds[handle] == sp)
15461da177e4SLinus Torvalds break;
15471da177e4SLinus Torvalds }
1548c9c5ced9SAndrew Vasquez spin_unlock_irqrestore(&ha->hardware_lock, flags);
15491da177e4SLinus Torvalds
15508d93f550SChad Dupuis if (handle == req->num_outstanding_cmds) {
15511da177e4SLinus Torvalds /* command not found */
15521da177e4SLinus Torvalds return QLA_FUNCTION_FAILED;
15531da177e4SLinus Torvalds }
15541da177e4SLinus Torvalds
15551da177e4SLinus Torvalds mcp->mb[0] = MBC_ABORT_COMMAND;
15561da177e4SLinus Torvalds if (HAS_EXTENDED_IDS(ha))
15571da177e4SLinus Torvalds mcp->mb[1] = fcport->loop_id;
15581da177e4SLinus Torvalds else
15591da177e4SLinus Torvalds mcp->mb[1] = fcport->loop_id << 8;
15601da177e4SLinus Torvalds mcp->mb[2] = (uint16_t)handle;
15611da177e4SLinus Torvalds mcp->mb[3] = (uint16_t)(handle >> 16);
15629ba56b95SGiridhar Malavali mcp->mb[6] = (uint16_t)cmd->device->lun;
15631da177e4SLinus Torvalds mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
15641da177e4SLinus Torvalds mcp->in_mb = MBX_0;
1565b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
15661da177e4SLinus Torvalds mcp->flags = 0;
15677b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
15681da177e4SLinus Torvalds
15691da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
15707c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
15711da177e4SLinus Torvalds } else {
15725f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
15735f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
15741da177e4SLinus Torvalds }
15751da177e4SLinus Torvalds
15761da177e4SLinus Torvalds return rval;
15771da177e4SLinus Torvalds }
15781da177e4SLinus Torvalds
15791da177e4SLinus Torvalds int
qla2x00_abort_target(struct fc_port * fcport,uint64_t l,int tag)15809cb78c16SHannes Reinecke qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
15811da177e4SLinus Torvalds {
1582523ec773SAndrew Vasquez int rval, rval2;
15831da177e4SLinus Torvalds mbx_cmd_t mc;
15841da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
15857b867cf7SAnirban Chakraborty scsi_qla_host_t *vha;
15861da177e4SLinus Torvalds
15877b867cf7SAnirban Chakraborty vha = fcport->vha;
15887c3df132SSaurav Kashyap
15895f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
15905f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
15917c3df132SSaurav Kashyap
15921da177e4SLinus Torvalds mcp->mb[0] = MBC_ABORT_TARGET;
1593523ec773SAndrew Vasquez mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
15947b867cf7SAnirban Chakraborty if (HAS_EXTENDED_IDS(vha->hw)) {
15951da177e4SLinus Torvalds mcp->mb[1] = fcport->loop_id;
15961da177e4SLinus Torvalds mcp->mb[10] = 0;
15971da177e4SLinus Torvalds mcp->out_mb |= MBX_10;
15981da177e4SLinus Torvalds } else {
15991da177e4SLinus Torvalds mcp->mb[1] = fcport->loop_id << 8;
16001da177e4SLinus Torvalds }
16017b867cf7SAnirban Chakraborty mcp->mb[2] = vha->hw->loop_reset_delay;
16027b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
16031da177e4SLinus Torvalds
16041da177e4SLinus Torvalds mcp->in_mb = MBX_0;
1605b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
16061da177e4SLinus Torvalds mcp->flags = 0;
16077b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
16081da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
16095f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
16105f28d2d7SSaurav Kashyap "Failed=%x.\n", rval);
1611523ec773SAndrew Vasquez }
1612523ec773SAndrew Vasquez
1613523ec773SAndrew Vasquez /* Issue marker IOCB. */
16149eb9c6dcSQuinn Tran rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, 0,
161573208dfdSAnirban Chakraborty MK_SYNC_ID);
1616523ec773SAndrew Vasquez if (rval2 != QLA_SUCCESS) {
16177c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1040,
16187c3df132SSaurav Kashyap "Failed to issue marker IOCB (%x).\n", rval2);
16191da177e4SLinus Torvalds } else {
16205f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
16215f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
1622523ec773SAndrew Vasquez }
1623523ec773SAndrew Vasquez
1624523ec773SAndrew Vasquez return rval;
1625523ec773SAndrew Vasquez }
1626523ec773SAndrew Vasquez
1627523ec773SAndrew Vasquez int
qla2x00_lun_reset(struct fc_port * fcport,uint64_t l,int tag)16289cb78c16SHannes Reinecke qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
1629523ec773SAndrew Vasquez {
1630523ec773SAndrew Vasquez int rval, rval2;
1631523ec773SAndrew Vasquez mbx_cmd_t mc;
1632523ec773SAndrew Vasquez mbx_cmd_t *mcp = &mc;
16337b867cf7SAnirban Chakraborty scsi_qla_host_t *vha;
1634523ec773SAndrew Vasquez
16357b867cf7SAnirban Chakraborty vha = fcport->vha;
16367c3df132SSaurav Kashyap
16375f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
16385f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
16397c3df132SSaurav Kashyap
1640523ec773SAndrew Vasquez mcp->mb[0] = MBC_LUN_RESET;
1641523ec773SAndrew Vasquez mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
16427b867cf7SAnirban Chakraborty if (HAS_EXTENDED_IDS(vha->hw))
1643523ec773SAndrew Vasquez mcp->mb[1] = fcport->loop_id;
1644523ec773SAndrew Vasquez else
1645523ec773SAndrew Vasquez mcp->mb[1] = fcport->loop_id << 8;
16469cb78c16SHannes Reinecke mcp->mb[2] = (u32)l;
1647523ec773SAndrew Vasquez mcp->mb[3] = 0;
16487b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
1649523ec773SAndrew Vasquez
1650523ec773SAndrew Vasquez mcp->in_mb = MBX_0;
1651b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
1652523ec773SAndrew Vasquez mcp->flags = 0;
16537b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
1654523ec773SAndrew Vasquez if (rval != QLA_SUCCESS) {
16557c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
1656523ec773SAndrew Vasquez }
1657523ec773SAndrew Vasquez
1658523ec773SAndrew Vasquez /* Issue marker IOCB. */
16599eb9c6dcSQuinn Tran rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, l,
166073208dfdSAnirban Chakraborty MK_SYNC_ID_LUN);
1661523ec773SAndrew Vasquez if (rval2 != QLA_SUCCESS) {
16627c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1044,
16637c3df132SSaurav Kashyap "Failed to issue marker IOCB (%x).\n", rval2);
1664523ec773SAndrew Vasquez } else {
16655f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
16665f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
16671da177e4SLinus Torvalds }
16681da177e4SLinus Torvalds
16691da177e4SLinus Torvalds return rval;
16701da177e4SLinus Torvalds }
16711da177e4SLinus Torvalds
16721da177e4SLinus Torvalds /*
16731da177e4SLinus Torvalds * qla2x00_get_adapter_id
16741da177e4SLinus Torvalds * Get adapter ID and topology.
16751da177e4SLinus Torvalds *
16761da177e4SLinus Torvalds * Input:
16771da177e4SLinus Torvalds * ha = adapter block pointer.
16781da177e4SLinus Torvalds * id = pointer for loop ID.
16791da177e4SLinus Torvalds * al_pa = pointer for AL_PA.
16801da177e4SLinus Torvalds * area = pointer for area.
16811da177e4SLinus Torvalds * domain = pointer for domain.
16821da177e4SLinus Torvalds * top = pointer for topology.
16831da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
16841da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
16851da177e4SLinus Torvalds *
16861da177e4SLinus Torvalds * Returns:
16871da177e4SLinus Torvalds * qla2x00 local function return status code.
16881da177e4SLinus Torvalds *
16891da177e4SLinus Torvalds * Context:
16901da177e4SLinus Torvalds * Kernel context.
16911da177e4SLinus Torvalds */
16921da177e4SLinus Torvalds int
qla2x00_get_adapter_id(scsi_qla_host_t * vha,uint16_t * id,uint8_t * al_pa,uint8_t * area,uint8_t * domain,uint16_t * top,uint16_t * sw_cap)16937b867cf7SAnirban Chakraborty qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
16942c3dfe3fSSeokmann Ju uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
16951da177e4SLinus Torvalds {
16961da177e4SLinus Torvalds int rval;
16971da177e4SLinus Torvalds mbx_cmd_t mc;
16981da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
16991da177e4SLinus Torvalds
17005f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
17015f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
17021da177e4SLinus Torvalds
17031da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
17047b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
1705eb66dc60SAndrew Vasquez mcp->out_mb = MBX_9|MBX_0;
17062c3dfe3fSSeokmann Ju mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
17076246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(vha->hw))
1708bad7001cSAndrew Vasquez mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
17097c9c4766SJoe Carnuccio if (IS_FWI2_CAPABLE(vha->hw))
17107c9c4766SJoe Carnuccio mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
171139200687SEwan D. Milne if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw))
171239200687SEwan D. Milne mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23;
17139f2475feSShyam Sundar
1714b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
17151da177e4SLinus Torvalds mcp->flags = 0;
17167b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
171733135aa2SRavi Anand if (mcp->mb[0] == MBS_COMMAND_ERROR)
171833135aa2SRavi Anand rval = QLA_COMMAND_ERROR;
171942e421b1SAndrew Vasquez else if (mcp->mb[0] == MBS_INVALID_COMMAND)
172042e421b1SAndrew Vasquez rval = QLA_INVALID_COMMAND;
17211da177e4SLinus Torvalds
17221da177e4SLinus Torvalds /* Return data. */
17231da177e4SLinus Torvalds *id = mcp->mb[1];
17241da177e4SLinus Torvalds *al_pa = LSB(mcp->mb[2]);
17251da177e4SLinus Torvalds *area = MSB(mcp->mb[2]);
17261da177e4SLinus Torvalds *domain = LSB(mcp->mb[3]);
17271da177e4SLinus Torvalds *top = mcp->mb[6];
17282c3dfe3fSSeokmann Ju *sw_cap = mcp->mb[7];
17291da177e4SLinus Torvalds
17301da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
17311da177e4SLinus Torvalds /*EMPTY*/
17327c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
17331da177e4SLinus Torvalds } else {
17345f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
17355f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
1736bad7001cSAndrew Vasquez
17376246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(vha->hw)) {
1738bad7001cSAndrew Vasquez vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1739bad7001cSAndrew Vasquez vha->fcoe_fcf_idx = mcp->mb[10];
1740bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1741bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1742bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1743bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1744bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1745bad7001cSAndrew Vasquez vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1746bad7001cSAndrew Vasquez }
17477c9c4766SJoe Carnuccio /* If FA-WWN supported */
1748d6b9b42bSSaurav Kashyap if (IS_FAWWN_CAPABLE(vha->hw)) {
17497c9c4766SJoe Carnuccio if (mcp->mb[7] & BIT_14) {
17507c9c4766SJoe Carnuccio vha->port_name[0] = MSB(mcp->mb[16]);
17517c9c4766SJoe Carnuccio vha->port_name[1] = LSB(mcp->mb[16]);
17527c9c4766SJoe Carnuccio vha->port_name[2] = MSB(mcp->mb[17]);
17537c9c4766SJoe Carnuccio vha->port_name[3] = LSB(mcp->mb[17]);
17547c9c4766SJoe Carnuccio vha->port_name[4] = MSB(mcp->mb[18]);
17557c9c4766SJoe Carnuccio vha->port_name[5] = LSB(mcp->mb[18]);
17567c9c4766SJoe Carnuccio vha->port_name[6] = MSB(mcp->mb[19]);
17577c9c4766SJoe Carnuccio vha->port_name[7] = LSB(mcp->mb[19]);
17587c9c4766SJoe Carnuccio fc_host_port_name(vha->host) =
17597c9c4766SJoe Carnuccio wwn_to_u64(vha->port_name);
17607c9c4766SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x10ca,
17617c9c4766SJoe Carnuccio "FA-WWN acquired %016llx\n",
17627c9c4766SJoe Carnuccio wwn_to_u64(vha->port_name));
17637c9c4766SJoe Carnuccio }
17641da177e4SLinus Torvalds }
1765969a6199SSawan Chandak
17669f2475feSShyam Sundar if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
1767969a6199SSawan Chandak vha->bbcr = mcp->mb[15];
17689f2475feSShyam Sundar if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) {
17699f2475feSShyam Sundar ql_log(ql_log_info, vha, 0x11a4,
17709f2475feSShyam Sundar "SCM: EDC ELS completed, flags 0x%x\n",
17719f2475feSShyam Sundar mcp->mb[21]);
17729f2475feSShyam Sundar }
17739f2475feSShyam Sundar if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) {
17749f2475feSShyam Sundar vha->hw->flags.scm_enabled = 1;
17759f2475feSShyam Sundar vha->scm_fabric_connection_flags |=
17769f2475feSShyam Sundar SCM_FLAG_RDF_COMPLETED;
17779f2475feSShyam Sundar ql_log(ql_log_info, vha, 0x11a5,
17789f2475feSShyam Sundar "SCM: RDF ELS completed, flags 0x%x\n",
17799f2475feSShyam Sundar mcp->mb[23]);
17809f2475feSShyam Sundar }
17819f2475feSShyam Sundar }
1782d6b9b42bSSaurav Kashyap }
17831da177e4SLinus Torvalds
17841da177e4SLinus Torvalds return rval;
17851da177e4SLinus Torvalds }
17861da177e4SLinus Torvalds
17871da177e4SLinus Torvalds /*
17881da177e4SLinus Torvalds * qla2x00_get_retry_cnt
17891da177e4SLinus Torvalds * Get current firmware login retry count and delay.
17901da177e4SLinus Torvalds *
17911da177e4SLinus Torvalds * Input:
17921da177e4SLinus Torvalds * ha = adapter block pointer.
17931da177e4SLinus Torvalds * retry_cnt = pointer to login retry count.
17941da177e4SLinus Torvalds * tov = pointer to login timeout value.
17951da177e4SLinus Torvalds *
17961da177e4SLinus Torvalds * Returns:
17971da177e4SLinus Torvalds * qla2x00 local function return status code.
17981da177e4SLinus Torvalds *
17991da177e4SLinus Torvalds * Context:
18001da177e4SLinus Torvalds * Kernel context.
18011da177e4SLinus Torvalds */
18021da177e4SLinus Torvalds int
qla2x00_get_retry_cnt(scsi_qla_host_t * vha,uint8_t * retry_cnt,uint8_t * tov,uint16_t * r_a_tov)18037b867cf7SAnirban Chakraborty qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
18041da177e4SLinus Torvalds uint16_t *r_a_tov)
18051da177e4SLinus Torvalds {
18061da177e4SLinus Torvalds int rval;
18071da177e4SLinus Torvalds uint16_t ratov;
18081da177e4SLinus Torvalds mbx_cmd_t mc;
18091da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
18101da177e4SLinus Torvalds
18115f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
18125f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
18131da177e4SLinus Torvalds
18141da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_RETRY_COUNT;
18151da177e4SLinus Torvalds mcp->out_mb = MBX_0;
18161da177e4SLinus Torvalds mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1817b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
18181da177e4SLinus Torvalds mcp->flags = 0;
18197b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
18201da177e4SLinus Torvalds
18211da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
18221da177e4SLinus Torvalds /*EMPTY*/
18237c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x104a,
18247c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
18251da177e4SLinus Torvalds } else {
18261da177e4SLinus Torvalds /* Convert returned data and check our values. */
18271da177e4SLinus Torvalds *r_a_tov = mcp->mb[3] / 2;
18281da177e4SLinus Torvalds ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
18291da177e4SLinus Torvalds if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
18301da177e4SLinus Torvalds /* Update to the larger values */
18311da177e4SLinus Torvalds *retry_cnt = (uint8_t)mcp->mb[1];
18321da177e4SLinus Torvalds *tov = ratov;
18331da177e4SLinus Torvalds }
18341da177e4SLinus Torvalds
18355f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
18367c3df132SSaurav Kashyap "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
18371da177e4SLinus Torvalds }
18381da177e4SLinus Torvalds
18391da177e4SLinus Torvalds return rval;
18401da177e4SLinus Torvalds }
18411da177e4SLinus Torvalds
18421da177e4SLinus Torvalds /*
18431da177e4SLinus Torvalds * qla2x00_init_firmware
18441da177e4SLinus Torvalds * Initialize adapter firmware.
18451da177e4SLinus Torvalds *
18461da177e4SLinus Torvalds * Input:
18471da177e4SLinus Torvalds * ha = adapter block pointer.
18481da177e4SLinus Torvalds * dptr = Initialization control block pointer.
18491da177e4SLinus Torvalds * size = size of initialization control block.
18501da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
18511da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
18521da177e4SLinus Torvalds *
18531da177e4SLinus Torvalds * Returns:
18541da177e4SLinus Torvalds * qla2x00 local function return status code.
18551da177e4SLinus Torvalds *
18561da177e4SLinus Torvalds * Context:
18571da177e4SLinus Torvalds * Kernel context.
18581da177e4SLinus Torvalds */
18591da177e4SLinus Torvalds int
qla2x00_init_firmware(scsi_qla_host_t * vha,uint16_t size)18607b867cf7SAnirban Chakraborty qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
18611da177e4SLinus Torvalds {
18621da177e4SLinus Torvalds int rval;
18631da177e4SLinus Torvalds mbx_cmd_t mc;
18641da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
18657b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
18661da177e4SLinus Torvalds
18675f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
18685f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
18691da177e4SLinus Torvalds
18707ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha) && ql2xdbwr)
18718dfa4b5aSBart Van Assche qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
1872a9083016SGiridhar Malavali (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1873a9083016SGiridhar Malavali
1874e6e074f1SAndrew Vasquez if (ha->flags.npiv_supported)
18752c3dfe3fSSeokmann Ju mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
18762c3dfe3fSSeokmann Ju else
18771da177e4SLinus Torvalds mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
18782c3dfe3fSSeokmann Ju
1879b64b0e8fSAndrew Vasquez mcp->mb[1] = 0;
18801da177e4SLinus Torvalds mcp->mb[2] = MSW(ha->init_cb_dma);
18811da177e4SLinus Torvalds mcp->mb[3] = LSW(ha->init_cb_dma);
18821da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
18831da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
1884b64b0e8fSAndrew Vasquez mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
18854ef21bd4SJoe Carnuccio if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
1886b64b0e8fSAndrew Vasquez mcp->mb[1] = BIT_0;
1887b64b0e8fSAndrew Vasquez mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1888b64b0e8fSAndrew Vasquez mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1889b64b0e8fSAndrew Vasquez mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1890b64b0e8fSAndrew Vasquez mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1891b64b0e8fSAndrew Vasquez mcp->mb[14] = sizeof(*ha->ex_init_cb);
1892b64b0e8fSAndrew Vasquez mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1893b64b0e8fSAndrew Vasquez }
18949f2475feSShyam Sundar
1895cf3c54fbSSaurav Kashyap if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) {
18969f2475feSShyam Sundar mcp->mb[1] |= BIT_1;
18979f2475feSShyam Sundar mcp->mb[16] = MSW(ha->sf_init_cb_dma);
18989f2475feSShyam Sundar mcp->mb[17] = LSW(ha->sf_init_cb_dma);
18999f2475feSShyam Sundar mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma));
19009f2475feSShyam Sundar mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma));
19019f2475feSShyam Sundar mcp->mb[15] = sizeof(*ha->sf_init_cb);
19029f2475feSShyam Sundar mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15;
19039f2475feSShyam Sundar }
19049f2475feSShyam Sundar
19056246b8a1SGiridhar Malavali /* 1 and 2 should normally be captured. */
19066246b8a1SGiridhar Malavali mcp->in_mb = MBX_2|MBX_1|MBX_0;
1907ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
19086246b8a1SGiridhar Malavali /* mb3 is additional info about the installed SFP. */
19096246b8a1SGiridhar Malavali mcp->in_mb |= MBX_3;
19101da177e4SLinus Torvalds mcp->buf_size = size;
19111da177e4SLinus Torvalds mcp->flags = MBX_DMA_OUT;
1912b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
19137b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
19141da177e4SLinus Torvalds
19151da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
19161da177e4SLinus Torvalds /*EMPTY*/
19177c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x104d,
1918f8f97b0cSJoe Carnuccio "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x.\n",
19196246b8a1SGiridhar Malavali rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
1920f8f97b0cSJoe Carnuccio if (ha->init_cb) {
1921f8f97b0cSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x104d, "init_cb:\n");
1922f8f97b0cSJoe Carnuccio ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha,
1923f8f97b0cSJoe Carnuccio 0x0104d, ha->init_cb, sizeof(*ha->init_cb));
1924f8f97b0cSJoe Carnuccio }
1925f8f97b0cSJoe Carnuccio if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
1926f8f97b0cSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x104d, "ex_init_cb:\n");
1927f8f97b0cSJoe Carnuccio ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha,
1928f8f97b0cSJoe Carnuccio 0x0104d, ha->ex_init_cb, sizeof(*ha->ex_init_cb));
1929f8f97b0cSJoe Carnuccio }
19301da177e4SLinus Torvalds } else {
1931ecc89f25SJoe Carnuccio if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
193292d4408eSSawan Chandak if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
193392d4408eSSawan Chandak ql_dbg(ql_dbg_mbx, vha, 0x119d,
193492d4408eSSawan Chandak "Invalid SFP/Validation Failed\n");
193592d4408eSSawan Chandak }
19365f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
19375f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
19381da177e4SLinus Torvalds }
19391da177e4SLinus Torvalds
19401da177e4SLinus Torvalds return rval;
19411da177e4SLinus Torvalds }
19421da177e4SLinus Torvalds
19432d70c103SNicholas Bellinger
19442d70c103SNicholas Bellinger /*
19451da177e4SLinus Torvalds * qla2x00_get_port_database
19461da177e4SLinus Torvalds * Issue normal/enhanced get port database mailbox command
19471da177e4SLinus Torvalds * and copy device name as necessary.
19481da177e4SLinus Torvalds *
19491da177e4SLinus Torvalds * Input:
19501da177e4SLinus Torvalds * ha = adapter state pointer.
19511da177e4SLinus Torvalds * dev = structure pointer.
19521da177e4SLinus Torvalds * opt = enhanced cmd option byte.
19531da177e4SLinus Torvalds *
19541da177e4SLinus Torvalds * Returns:
19551da177e4SLinus Torvalds * qla2x00 local function return status code.
19561da177e4SLinus Torvalds *
19571da177e4SLinus Torvalds * Context:
19581da177e4SLinus Torvalds * Kernel context.
19591da177e4SLinus Torvalds */
19601da177e4SLinus Torvalds int
qla2x00_get_port_database(scsi_qla_host_t * vha,fc_port_t * fcport,uint8_t opt)19617b867cf7SAnirban Chakraborty qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
19621da177e4SLinus Torvalds {
19631da177e4SLinus Torvalds int rval;
19641da177e4SLinus Torvalds mbx_cmd_t mc;
19651da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
19661da177e4SLinus Torvalds port_database_t *pd;
19671c7c6357SAndrew Vasquez struct port_database_24xx *pd24;
19681da177e4SLinus Torvalds dma_addr_t pd_dma;
19697b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
19701da177e4SLinus Torvalds
19715f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
19725f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
19731da177e4SLinus Torvalds
19741c7c6357SAndrew Vasquez pd24 = NULL;
197508eb7f45SThomas Meyer pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
19761da177e4SLinus Torvalds if (pd == NULL) {
19777c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x1050,
19787c3df132SSaurav Kashyap "Failed to allocate port database structure.\n");
1979edd05de1SDuane Grigsby fcport->query = 0;
19801da177e4SLinus Torvalds return QLA_MEMORY_ALLOC_FAILED;
19811da177e4SLinus Torvalds }
19821da177e4SLinus Torvalds
19831da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_PORT_DATABASE;
1984e428924cSAndrew Vasquez if (opt != 0 && !IS_FWI2_CAPABLE(ha))
19851c7c6357SAndrew Vasquez mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
19861da177e4SLinus Torvalds mcp->mb[2] = MSW(pd_dma);
19871da177e4SLinus Torvalds mcp->mb[3] = LSW(pd_dma);
19881da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(pd_dma));
19891da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(pd_dma));
19907b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
19912c3dfe3fSSeokmann Ju mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
19921da177e4SLinus Torvalds mcp->in_mb = MBX_0;
1993e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
19941c7c6357SAndrew Vasquez mcp->mb[1] = fcport->loop_id;
19951c7c6357SAndrew Vasquez mcp->mb[10] = opt;
19961c7c6357SAndrew Vasquez mcp->out_mb |= MBX_10|MBX_1;
19971c7c6357SAndrew Vasquez mcp->in_mb |= MBX_1;
19981c7c6357SAndrew Vasquez } else if (HAS_EXTENDED_IDS(ha)) {
19991c7c6357SAndrew Vasquez mcp->mb[1] = fcport->loop_id;
20001c7c6357SAndrew Vasquez mcp->mb[10] = opt;
20011c7c6357SAndrew Vasquez mcp->out_mb |= MBX_10|MBX_1;
20021c7c6357SAndrew Vasquez } else {
20031c7c6357SAndrew Vasquez mcp->mb[1] = fcport->loop_id << 8 | opt;
20041c7c6357SAndrew Vasquez mcp->out_mb |= MBX_1;
20051c7c6357SAndrew Vasquez }
2006e428924cSAndrew Vasquez mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
2007e428924cSAndrew Vasquez PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
20081da177e4SLinus Torvalds mcp->flags = MBX_DMA_IN;
20091da177e4SLinus Torvalds mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
20107b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
20111da177e4SLinus Torvalds if (rval != QLA_SUCCESS)
20121da177e4SLinus Torvalds goto gpd_error_out;
20131da177e4SLinus Torvalds
2014e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
20150eba25dfSArun Easi uint64_t zero = 0;
2016c0c462c8SDuane Grigsby u8 current_login_state, last_login_state;
2017c0c462c8SDuane Grigsby
20181c7c6357SAndrew Vasquez pd24 = (struct port_database_24xx *) pd;
20191c7c6357SAndrew Vasquez
20201c7c6357SAndrew Vasquez /* Check for logged in state. */
202184ed362aSMichael Hernandez if (NVME_TARGET(ha, fcport)) {
2022c0c462c8SDuane Grigsby current_login_state = pd24->current_login_state >> 4;
2023c0c462c8SDuane Grigsby last_login_state = pd24->last_login_state >> 4;
2024c0c462c8SDuane Grigsby } else {
2025c0c462c8SDuane Grigsby current_login_state = pd24->current_login_state & 0xf;
2026c0c462c8SDuane Grigsby last_login_state = pd24->last_login_state & 0xf;
2027c0c462c8SDuane Grigsby }
2028c0c462c8SDuane Grigsby fcport->current_login_state = pd24->current_login_state;
2029c0c462c8SDuane Grigsby fcport->last_login_state = pd24->last_login_state;
2030c0c462c8SDuane Grigsby
2031c0c462c8SDuane Grigsby /* Check for logged in state. */
2032c0c462c8SDuane Grigsby if (current_login_state != PDS_PRLI_COMPLETE &&
2033c0c462c8SDuane Grigsby last_login_state != PDS_PRLI_COMPLETE) {
2034c0c462c8SDuane Grigsby ql_dbg(ql_dbg_mbx, vha, 0x119a,
2035c0c462c8SDuane Grigsby "Unable to verify login-state (%x/%x) for loop_id %x.\n",
2036c0c462c8SDuane Grigsby current_login_state, last_login_state,
2037c0c462c8SDuane Grigsby fcport->loop_id);
20381c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
2039c0c462c8SDuane Grigsby
2040c0c462c8SDuane Grigsby if (!fcport->query)
20411c7c6357SAndrew Vasquez goto gpd_error_out;
20421c7c6357SAndrew Vasquez }
20431c7c6357SAndrew Vasquez
20440eba25dfSArun Easi if (fcport->loop_id == FC_NO_LOOP_ID ||
20450eba25dfSArun Easi (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
20460eba25dfSArun Easi memcmp(fcport->port_name, pd24->port_name, 8))) {
20470eba25dfSArun Easi /* We lost the device mid way. */
20480eba25dfSArun Easi rval = QLA_NOT_LOGGED_IN;
20490eba25dfSArun Easi goto gpd_error_out;
20500eba25dfSArun Easi }
20510eba25dfSArun Easi
20521c7c6357SAndrew Vasquez /* Names are little-endian. */
20531c7c6357SAndrew Vasquez memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
20541c7c6357SAndrew Vasquez memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
20551c7c6357SAndrew Vasquez
20561c7c6357SAndrew Vasquez /* Get port_id of device. */
20571c7c6357SAndrew Vasquez fcport->d_id.b.domain = pd24->port_id[0];
20581c7c6357SAndrew Vasquez fcport->d_id.b.area = pd24->port_id[1];
20591c7c6357SAndrew Vasquez fcport->d_id.b.al_pa = pd24->port_id[2];
20601c7c6357SAndrew Vasquez fcport->d_id.b.rsvd_1 = 0;
20611c7c6357SAndrew Vasquez
20621c7c6357SAndrew Vasquez /* If not target must be initiator or unknown type. */
20631c7c6357SAndrew Vasquez if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
20641c7c6357SAndrew Vasquez fcport->port_type = FCT_INITIATOR;
20651c7c6357SAndrew Vasquez else
20661c7c6357SAndrew Vasquez fcport->port_type = FCT_TARGET;
20672d70c103SNicholas Bellinger
20682d70c103SNicholas Bellinger /* Passback COS information. */
20692d70c103SNicholas Bellinger fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
20702d70c103SNicholas Bellinger FC_COS_CLASS2 : FC_COS_CLASS3;
20712d70c103SNicholas Bellinger
20722d70c103SNicholas Bellinger if (pd24->prli_svc_param_word_3[0] & BIT_7)
20732d70c103SNicholas Bellinger fcport->flags |= FCF_CONF_COMP_SUPPORTED;
20741c7c6357SAndrew Vasquez } else {
20750eba25dfSArun Easi uint64_t zero = 0;
20760eba25dfSArun Easi
20771da177e4SLinus Torvalds /* Check for logged in state. */
20781da177e4SLinus Torvalds if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
20791da177e4SLinus Torvalds pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
20807c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x100a,
20817c3df132SSaurav Kashyap "Unable to verify login-state (%x/%x) - "
20827c3df132SSaurav Kashyap "portid=%02x%02x%02x.\n", pd->master_state,
20837c3df132SSaurav Kashyap pd->slave_state, fcport->d_id.b.domain,
20847c3df132SSaurav Kashyap fcport->d_id.b.area, fcport->d_id.b.al_pa);
20851da177e4SLinus Torvalds rval = QLA_FUNCTION_FAILED;
20861da177e4SLinus Torvalds goto gpd_error_out;
20871da177e4SLinus Torvalds }
20881da177e4SLinus Torvalds
20890eba25dfSArun Easi if (fcport->loop_id == FC_NO_LOOP_ID ||
20900eba25dfSArun Easi (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
20910eba25dfSArun Easi memcmp(fcport->port_name, pd->port_name, 8))) {
20920eba25dfSArun Easi /* We lost the device mid way. */
20930eba25dfSArun Easi rval = QLA_NOT_LOGGED_IN;
20940eba25dfSArun Easi goto gpd_error_out;
20950eba25dfSArun Easi }
20960eba25dfSArun Easi
20971da177e4SLinus Torvalds /* Names are little-endian. */
20981da177e4SLinus Torvalds memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
20991da177e4SLinus Torvalds memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
21001da177e4SLinus Torvalds
21011da177e4SLinus Torvalds /* Get port_id of device. */
21021da177e4SLinus Torvalds fcport->d_id.b.domain = pd->port_id[0];
21031c7c6357SAndrew Vasquez fcport->d_id.b.area = pd->port_id[3];
21041c7c6357SAndrew Vasquez fcport->d_id.b.al_pa = pd->port_id[2];
21051da177e4SLinus Torvalds fcport->d_id.b.rsvd_1 = 0;
21061da177e4SLinus Torvalds
21071da177e4SLinus Torvalds /* If not target must be initiator or unknown type. */
21081da177e4SLinus Torvalds if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
21091da177e4SLinus Torvalds fcport->port_type = FCT_INITIATOR;
21101da177e4SLinus Torvalds else
21111da177e4SLinus Torvalds fcport->port_type = FCT_TARGET;
2112ad3e0edaSAndrew Vasquez
2113ad3e0edaSAndrew Vasquez /* Passback COS information. */
2114ad3e0edaSAndrew Vasquez fcport->supported_classes = (pd->options & BIT_4) ?
2115ad3e0edaSAndrew Vasquez FC_COS_CLASS2 : FC_COS_CLASS3;
21161c7c6357SAndrew Vasquez }
21171da177e4SLinus Torvalds
21181da177e4SLinus Torvalds gpd_error_out:
21191da177e4SLinus Torvalds dma_pool_free(ha->s_dma_pool, pd, pd_dma);
2120edd05de1SDuane Grigsby fcport->query = 0;
21211da177e4SLinus Torvalds
21221da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
21237c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1052,
21247c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
21257c3df132SSaurav Kashyap mcp->mb[0], mcp->mb[1]);
21261da177e4SLinus Torvalds } else {
21275f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
21285f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
21291da177e4SLinus Torvalds }
21301da177e4SLinus Torvalds
21311da177e4SLinus Torvalds return rval;
21321da177e4SLinus Torvalds }
21331da177e4SLinus Torvalds
2134818c7f87SJoe Carnuccio int
qla24xx_get_port_database(scsi_qla_host_t * vha,u16 nport_handle,struct port_database_24xx * pdb)2135818c7f87SJoe Carnuccio qla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle,
2136818c7f87SJoe Carnuccio struct port_database_24xx *pdb)
2137818c7f87SJoe Carnuccio {
2138818c7f87SJoe Carnuccio mbx_cmd_t mc;
2139818c7f87SJoe Carnuccio mbx_cmd_t *mcp = &mc;
2140818c7f87SJoe Carnuccio dma_addr_t pdb_dma;
2141818c7f87SJoe Carnuccio int rval;
2142818c7f87SJoe Carnuccio
2143818c7f87SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1115,
2144818c7f87SJoe Carnuccio "Entered %s.\n", __func__);
2145818c7f87SJoe Carnuccio
2146818c7f87SJoe Carnuccio memset(pdb, 0, sizeof(*pdb));
2147818c7f87SJoe Carnuccio
2148818c7f87SJoe Carnuccio pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb,
2149818c7f87SJoe Carnuccio sizeof(*pdb), DMA_FROM_DEVICE);
2150818c7f87SJoe Carnuccio if (!pdb_dma) {
2151818c7f87SJoe Carnuccio ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n");
2152818c7f87SJoe Carnuccio return QLA_MEMORY_ALLOC_FAILED;
2153818c7f87SJoe Carnuccio }
2154818c7f87SJoe Carnuccio
2155818c7f87SJoe Carnuccio mcp->mb[0] = MBC_GET_PORT_DATABASE;
2156818c7f87SJoe Carnuccio mcp->mb[1] = nport_handle;
2157818c7f87SJoe Carnuccio mcp->mb[2] = MSW(LSD(pdb_dma));
2158818c7f87SJoe Carnuccio mcp->mb[3] = LSW(LSD(pdb_dma));
2159818c7f87SJoe Carnuccio mcp->mb[6] = MSW(MSD(pdb_dma));
2160818c7f87SJoe Carnuccio mcp->mb[7] = LSW(MSD(pdb_dma));
2161818c7f87SJoe Carnuccio mcp->mb[9] = 0;
2162818c7f87SJoe Carnuccio mcp->mb[10] = 0;
2163818c7f87SJoe Carnuccio mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2164818c7f87SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
2165818c7f87SJoe Carnuccio mcp->buf_size = sizeof(*pdb);
2166818c7f87SJoe Carnuccio mcp->flags = MBX_DMA_IN;
2167818c7f87SJoe Carnuccio mcp->tov = vha->hw->login_timeout * 2;
2168818c7f87SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
2169818c7f87SJoe Carnuccio
2170818c7f87SJoe Carnuccio if (rval != QLA_SUCCESS) {
2171818c7f87SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x111a,
2172818c7f87SJoe Carnuccio "Failed=%x mb[0]=%x mb[1]=%x.\n",
2173818c7f87SJoe Carnuccio rval, mcp->mb[0], mcp->mb[1]);
2174818c7f87SJoe Carnuccio } else {
2175818c7f87SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111b,
2176818c7f87SJoe Carnuccio "Done %s.\n", __func__);
2177818c7f87SJoe Carnuccio }
2178818c7f87SJoe Carnuccio
2179818c7f87SJoe Carnuccio dma_unmap_single(&vha->hw->pdev->dev, pdb_dma,
2180818c7f87SJoe Carnuccio sizeof(*pdb), DMA_FROM_DEVICE);
2181818c7f87SJoe Carnuccio
2182818c7f87SJoe Carnuccio return rval;
2183818c7f87SJoe Carnuccio }
2184818c7f87SJoe Carnuccio
21851da177e4SLinus Torvalds /*
21861da177e4SLinus Torvalds * qla2x00_get_firmware_state
21871da177e4SLinus Torvalds * Get adapter firmware state.
21881da177e4SLinus Torvalds *
21891da177e4SLinus Torvalds * Input:
21901da177e4SLinus Torvalds * ha = adapter block pointer.
21911da177e4SLinus Torvalds * dptr = pointer for firmware state.
21921da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
21931da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
21941da177e4SLinus Torvalds *
21951da177e4SLinus Torvalds * Returns:
21961da177e4SLinus Torvalds * qla2x00 local function return status code.
21971da177e4SLinus Torvalds *
21981da177e4SLinus Torvalds * Context:
21991da177e4SLinus Torvalds * Kernel context.
22001da177e4SLinus Torvalds */
22011da177e4SLinus Torvalds int
qla2x00_get_firmware_state(scsi_qla_host_t * vha,uint16_t * states)22027b867cf7SAnirban Chakraborty qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
22031da177e4SLinus Torvalds {
22041da177e4SLinus Torvalds int rval;
22051da177e4SLinus Torvalds mbx_cmd_t mc;
22061da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
220792d4408eSSawan Chandak struct qla_hw_data *ha = vha->hw;
22081da177e4SLinus Torvalds
22095f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
22105f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
22111da177e4SLinus Torvalds
2212efa74a62SQuinn Tran if (!ha->flags.fw_started)
2213efa74a62SQuinn Tran return QLA_FUNCTION_FAILED;
2214efa74a62SQuinn Tran
22151da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
22161da177e4SLinus Torvalds mcp->out_mb = MBX_0;
22179d2683c0SAndrew Vasquez if (IS_FWI2_CAPABLE(vha->hw))
2218b5a340ddSJoe Carnuccio mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
22199d2683c0SAndrew Vasquez else
22209d2683c0SAndrew Vasquez mcp->in_mb = MBX_1|MBX_0;
2221b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
22221da177e4SLinus Torvalds mcp->flags = 0;
22237b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
22241da177e4SLinus Torvalds
22254d4df193SHarihara Kadayam /* Return firmware states. */
22264d4df193SHarihara Kadayam states[0] = mcp->mb[1];
22279d2683c0SAndrew Vasquez if (IS_FWI2_CAPABLE(vha->hw)) {
22284d4df193SHarihara Kadayam states[1] = mcp->mb[2];
2229ec891462SJoe Carnuccio states[2] = mcp->mb[3]; /* SFP info */
2230656e8912SAndrew Vasquez states[3] = mcp->mb[4];
2231656e8912SAndrew Vasquez states[4] = mcp->mb[5];
2232b5a340ddSJoe Carnuccio states[5] = mcp->mb[6]; /* DPORT status */
22339d2683c0SAndrew Vasquez }
22341da177e4SLinus Torvalds
22351da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
22361da177e4SLinus Torvalds /*EMPTY*/
22377c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
22381da177e4SLinus Torvalds } else {
2239ecc89f25SJoe Carnuccio if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
224092d4408eSSawan Chandak if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
224192d4408eSSawan Chandak ql_dbg(ql_dbg_mbx, vha, 0x119e,
224292d4408eSSawan Chandak "Invalid SFP/Validation Failed\n");
224392d4408eSSawan Chandak }
22445f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
22455f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
22461da177e4SLinus Torvalds }
22471da177e4SLinus Torvalds
22481da177e4SLinus Torvalds return rval;
22491da177e4SLinus Torvalds }
22501da177e4SLinus Torvalds
22511da177e4SLinus Torvalds /*
22521da177e4SLinus Torvalds * qla2x00_get_port_name
22531da177e4SLinus Torvalds * Issue get port name mailbox command.
22541da177e4SLinus Torvalds * Returned name is in big endian format.
22551da177e4SLinus Torvalds *
22561da177e4SLinus Torvalds * Input:
22571da177e4SLinus Torvalds * ha = adapter block pointer.
22581da177e4SLinus Torvalds * loop_id = loop ID of device.
22591da177e4SLinus Torvalds * name = pointer for name.
22601da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
22611da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
22621da177e4SLinus Torvalds *
22631da177e4SLinus Torvalds * Returns:
22641da177e4SLinus Torvalds * qla2x00 local function return status code.
22651da177e4SLinus Torvalds *
22661da177e4SLinus Torvalds * Context:
22671da177e4SLinus Torvalds * Kernel context.
22681da177e4SLinus Torvalds */
22691da177e4SLinus Torvalds int
qla2x00_get_port_name(scsi_qla_host_t * vha,uint16_t loop_id,uint8_t * name,uint8_t opt)22707b867cf7SAnirban Chakraborty qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
22711da177e4SLinus Torvalds uint8_t opt)
22721da177e4SLinus Torvalds {
22731da177e4SLinus Torvalds int rval;
22741da177e4SLinus Torvalds mbx_cmd_t mc;
22751da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
22761da177e4SLinus Torvalds
22775f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
22785f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
22791da177e4SLinus Torvalds
22801da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_PORT_NAME;
22817b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
22822c3dfe3fSSeokmann Ju mcp->out_mb = MBX_9|MBX_1|MBX_0;
22837b867cf7SAnirban Chakraborty if (HAS_EXTENDED_IDS(vha->hw)) {
22841da177e4SLinus Torvalds mcp->mb[1] = loop_id;
22851da177e4SLinus Torvalds mcp->mb[10] = opt;
22861da177e4SLinus Torvalds mcp->out_mb |= MBX_10;
22871da177e4SLinus Torvalds } else {
22881da177e4SLinus Torvalds mcp->mb[1] = loop_id << 8 | opt;
22891da177e4SLinus Torvalds }
22901da177e4SLinus Torvalds
22911da177e4SLinus Torvalds mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2292b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
22931da177e4SLinus Torvalds mcp->flags = 0;
22947b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
22951da177e4SLinus Torvalds
22961da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
22971da177e4SLinus Torvalds /*EMPTY*/
22987c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
22991da177e4SLinus Torvalds } else {
23001da177e4SLinus Torvalds if (name != NULL) {
23011da177e4SLinus Torvalds /* This function returns name in big endian. */
23021196ae02SRichard Lary name[0] = MSB(mcp->mb[2]);
23031196ae02SRichard Lary name[1] = LSB(mcp->mb[2]);
23041196ae02SRichard Lary name[2] = MSB(mcp->mb[3]);
23051196ae02SRichard Lary name[3] = LSB(mcp->mb[3]);
23061196ae02SRichard Lary name[4] = MSB(mcp->mb[6]);
23071196ae02SRichard Lary name[5] = LSB(mcp->mb[6]);
23081196ae02SRichard Lary name[6] = MSB(mcp->mb[7]);
23091196ae02SRichard Lary name[7] = LSB(mcp->mb[7]);
23101da177e4SLinus Torvalds }
23111da177e4SLinus Torvalds
23125f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
23135f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
23141da177e4SLinus Torvalds }
23151da177e4SLinus Torvalds
23161da177e4SLinus Torvalds return rval;
23171da177e4SLinus Torvalds }
23181da177e4SLinus Torvalds
23191da177e4SLinus Torvalds /*
232061e1b269SJoe Carnuccio * qla24xx_link_initialization
232161e1b269SJoe Carnuccio * Issue link initialization mailbox command.
232261e1b269SJoe Carnuccio *
232361e1b269SJoe Carnuccio * Input:
232461e1b269SJoe Carnuccio * ha = adapter block pointer.
232561e1b269SJoe Carnuccio * TARGET_QUEUE_LOCK must be released.
232661e1b269SJoe Carnuccio * ADAPTER_STATE_LOCK must be released.
232761e1b269SJoe Carnuccio *
232861e1b269SJoe Carnuccio * Returns:
232961e1b269SJoe Carnuccio * qla2x00 local function return status code.
233061e1b269SJoe Carnuccio *
233161e1b269SJoe Carnuccio * Context:
233261e1b269SJoe Carnuccio * Kernel context.
233361e1b269SJoe Carnuccio */
233461e1b269SJoe Carnuccio int
qla24xx_link_initialize(scsi_qla_host_t * vha)233561e1b269SJoe Carnuccio qla24xx_link_initialize(scsi_qla_host_t *vha)
233661e1b269SJoe Carnuccio {
233761e1b269SJoe Carnuccio int rval;
233861e1b269SJoe Carnuccio mbx_cmd_t mc;
233961e1b269SJoe Carnuccio mbx_cmd_t *mcp = &mc;
234061e1b269SJoe Carnuccio
234161e1b269SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
234261e1b269SJoe Carnuccio "Entered %s.\n", __func__);
234361e1b269SJoe Carnuccio
234461e1b269SJoe Carnuccio if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
234561e1b269SJoe Carnuccio return QLA_FUNCTION_FAILED;
234661e1b269SJoe Carnuccio
234761e1b269SJoe Carnuccio mcp->mb[0] = MBC_LINK_INITIALIZATION;
23485a5c27b6SJoe Carnuccio mcp->mb[1] = BIT_4;
23495a5c27b6SJoe Carnuccio if (vha->hw->operating_mode == LOOP)
23505a5c27b6SJoe Carnuccio mcp->mb[1] |= BIT_6;
23515a5c27b6SJoe Carnuccio else
23525a5c27b6SJoe Carnuccio mcp->mb[1] |= BIT_5;
235361e1b269SJoe Carnuccio mcp->mb[2] = 0;
235461e1b269SJoe Carnuccio mcp->mb[3] = 0;
235561e1b269SJoe Carnuccio mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
235661e1b269SJoe Carnuccio mcp->in_mb = MBX_0;
235761e1b269SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
235861e1b269SJoe Carnuccio mcp->flags = 0;
235961e1b269SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
236061e1b269SJoe Carnuccio
236161e1b269SJoe Carnuccio if (rval != QLA_SUCCESS) {
236261e1b269SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
236361e1b269SJoe Carnuccio } else {
236461e1b269SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
236561e1b269SJoe Carnuccio "Done %s.\n", __func__);
236661e1b269SJoe Carnuccio }
236761e1b269SJoe Carnuccio
236861e1b269SJoe Carnuccio return rval;
236961e1b269SJoe Carnuccio }
237061e1b269SJoe Carnuccio
237161e1b269SJoe Carnuccio /*
23721da177e4SLinus Torvalds * qla2x00_lip_reset
23731da177e4SLinus Torvalds * Issue LIP reset mailbox command.
23741da177e4SLinus Torvalds *
23751da177e4SLinus Torvalds * Input:
23761da177e4SLinus Torvalds * ha = adapter block pointer.
23771da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
23781da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
23791da177e4SLinus Torvalds *
23801da177e4SLinus Torvalds * Returns:
23811da177e4SLinus Torvalds * qla2x00 local function return status code.
23821da177e4SLinus Torvalds *
23831da177e4SLinus Torvalds * Context:
23841da177e4SLinus Torvalds * Kernel context.
23851da177e4SLinus Torvalds */
23861da177e4SLinus Torvalds int
qla2x00_lip_reset(scsi_qla_host_t * vha)23877b867cf7SAnirban Chakraborty qla2x00_lip_reset(scsi_qla_host_t *vha)
23881da177e4SLinus Torvalds {
23891da177e4SLinus Torvalds int rval;
23901da177e4SLinus Torvalds mbx_cmd_t mc;
23911da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
23921da177e4SLinus Torvalds
23937f2a398dSQuinn Tran ql_dbg(ql_dbg_disc, vha, 0x105a,
23945f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
23951da177e4SLinus Torvalds
23966246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(vha->hw)) {
23973a03eb79SAndrew Vasquez /* Logout across all FCFs. */
23983a03eb79SAndrew Vasquez mcp->mb[0] = MBC_LIP_FULL_LOGIN;
23993a03eb79SAndrew Vasquez mcp->mb[1] = BIT_1;
24003a03eb79SAndrew Vasquez mcp->mb[2] = 0;
24013a03eb79SAndrew Vasquez mcp->out_mb = MBX_2|MBX_1|MBX_0;
24023a03eb79SAndrew Vasquez } else if (IS_FWI2_CAPABLE(vha->hw)) {
24031c7c6357SAndrew Vasquez mcp->mb[0] = MBC_LIP_FULL_LOGIN;
240487d6814aSQuinn Tran mcp->mb[1] = BIT_4;
24050c8c39afSAndrew Vasquez mcp->mb[2] = 0;
24067b867cf7SAnirban Chakraborty mcp->mb[3] = vha->hw->loop_reset_delay;
24071c7c6357SAndrew Vasquez mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
24081c7c6357SAndrew Vasquez } else {
24091da177e4SLinus Torvalds mcp->mb[0] = MBC_LIP_RESET;
24101da177e4SLinus Torvalds mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
24117b867cf7SAnirban Chakraborty if (HAS_EXTENDED_IDS(vha->hw)) {
24121da177e4SLinus Torvalds mcp->mb[1] = 0x00ff;
24131da177e4SLinus Torvalds mcp->mb[10] = 0;
24141da177e4SLinus Torvalds mcp->out_mb |= MBX_10;
24151da177e4SLinus Torvalds } else {
24161da177e4SLinus Torvalds mcp->mb[1] = 0xff00;
24171da177e4SLinus Torvalds }
24187b867cf7SAnirban Chakraborty mcp->mb[2] = vha->hw->loop_reset_delay;
24191da177e4SLinus Torvalds mcp->mb[3] = 0;
24201c7c6357SAndrew Vasquez }
24211da177e4SLinus Torvalds mcp->in_mb = MBX_0;
2422b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
24231da177e4SLinus Torvalds mcp->flags = 0;
24247b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
24251da177e4SLinus Torvalds
24261da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
24271da177e4SLinus Torvalds /*EMPTY*/
24287c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
24291da177e4SLinus Torvalds } else {
24301da177e4SLinus Torvalds /*EMPTY*/
24315f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
24325f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
24331da177e4SLinus Torvalds }
24341da177e4SLinus Torvalds
24351da177e4SLinus Torvalds return rval;
24361da177e4SLinus Torvalds }
24371da177e4SLinus Torvalds
24381da177e4SLinus Torvalds /*
24391da177e4SLinus Torvalds * qla2x00_send_sns
24401da177e4SLinus Torvalds * Send SNS command.
24411da177e4SLinus Torvalds *
24421da177e4SLinus Torvalds * Input:
24431da177e4SLinus Torvalds * ha = adapter block pointer.
24441da177e4SLinus Torvalds * sns = pointer for command.
24451da177e4SLinus Torvalds * cmd_size = command size.
24461da177e4SLinus Torvalds * buf_size = response/command size.
24471da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
24481da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
24491da177e4SLinus Torvalds *
24501da177e4SLinus Torvalds * Returns:
24511da177e4SLinus Torvalds * qla2x00 local function return status code.
24521da177e4SLinus Torvalds *
24531da177e4SLinus Torvalds * Context:
24541da177e4SLinus Torvalds * Kernel context.
24551da177e4SLinus Torvalds */
24561da177e4SLinus Torvalds int
qla2x00_send_sns(scsi_qla_host_t * vha,dma_addr_t sns_phys_address,uint16_t cmd_size,size_t buf_size)24577b867cf7SAnirban Chakraborty qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
24581da177e4SLinus Torvalds uint16_t cmd_size, size_t buf_size)
24591da177e4SLinus Torvalds {
24601da177e4SLinus Torvalds int rval;
24611da177e4SLinus Torvalds mbx_cmd_t mc;
24621da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
24631da177e4SLinus Torvalds
24645f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
24655f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
24661da177e4SLinus Torvalds
24675f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
24687c3df132SSaurav Kashyap "Retry cnt=%d ratov=%d total tov=%d.\n",
24697c3df132SSaurav Kashyap vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
24701da177e4SLinus Torvalds
24711da177e4SLinus Torvalds mcp->mb[0] = MBC_SEND_SNS_COMMAND;
24721da177e4SLinus Torvalds mcp->mb[1] = cmd_size;
24731da177e4SLinus Torvalds mcp->mb[2] = MSW(sns_phys_address);
24741da177e4SLinus Torvalds mcp->mb[3] = LSW(sns_phys_address);
24751da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(sns_phys_address));
24761da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(sns_phys_address));
24771da177e4SLinus Torvalds mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
24781da177e4SLinus Torvalds mcp->in_mb = MBX_0|MBX_1;
24791da177e4SLinus Torvalds mcp->buf_size = buf_size;
24801da177e4SLinus Torvalds mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
24817b867cf7SAnirban Chakraborty mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
24827b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
24831da177e4SLinus Torvalds
24841da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
24851da177e4SLinus Torvalds /*EMPTY*/
24867c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x105f,
24877c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
24887c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
24891da177e4SLinus Torvalds } else {
24901da177e4SLinus Torvalds /*EMPTY*/
24915f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
24925f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
24931da177e4SLinus Torvalds }
24941da177e4SLinus Torvalds
24951da177e4SLinus Torvalds return rval;
24961da177e4SLinus Torvalds }
24971da177e4SLinus Torvalds
24981c7c6357SAndrew Vasquez int
qla24xx_login_fabric(scsi_qla_host_t * vha,uint16_t loop_id,uint8_t domain,uint8_t area,uint8_t al_pa,uint16_t * mb,uint8_t opt)24997b867cf7SAnirban Chakraborty qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
25001c7c6357SAndrew Vasquez uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
25011c7c6357SAndrew Vasquez {
25021c7c6357SAndrew Vasquez int rval;
25031c7c6357SAndrew Vasquez
25041c7c6357SAndrew Vasquez struct logio_entry_24xx *lg;
25051c7c6357SAndrew Vasquez dma_addr_t lg_dma;
25061c7c6357SAndrew Vasquez uint32_t iop[2];
25077b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
25082afa19a9SAnirban Chakraborty struct req_que *req;
25091c7c6357SAndrew Vasquez
25105f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
25115f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
25121c7c6357SAndrew Vasquez
2513d7459527SMichael Hernandez if (vha->vp_idx && vha->qpair)
2514d7459527SMichael Hernandez req = vha->qpair->req;
251568ca949cSAnirban Chakraborty else
2516d7459527SMichael Hernandez req = ha->req_q_map[0];
25172afa19a9SAnirban Chakraborty
251808eb7f45SThomas Meyer lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
25191c7c6357SAndrew Vasquez if (lg == NULL) {
25207c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x1062,
25217c3df132SSaurav Kashyap "Failed to allocate login IOCB.\n");
25221c7c6357SAndrew Vasquez return QLA_MEMORY_ALLOC_FAILED;
25231c7c6357SAndrew Vasquez }
25241c7c6357SAndrew Vasquez
25251c7c6357SAndrew Vasquez lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
25261c7c6357SAndrew Vasquez lg->entry_count = 1;
2527c25eb70aSBart Van Assche lg->handle = make_handle(req->id, lg->handle);
25281c7c6357SAndrew Vasquez lg->nport_handle = cpu_to_le16(loop_id);
2529ad950360SBart Van Assche lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
25301c7c6357SAndrew Vasquez if (opt & BIT_0)
2531ad950360SBart Van Assche lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
25328baa51a6SAndrew Vasquez if (opt & BIT_1)
2533ad950360SBart Van Assche lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
25341c7c6357SAndrew Vasquez lg->port_id[0] = al_pa;
25351c7c6357SAndrew Vasquez lg->port_id[1] = area;
25361c7c6357SAndrew Vasquez lg->port_id[2] = domain;
25377b867cf7SAnirban Chakraborty lg->vp_index = vha->vp_idx;
25387f45dd0bSAndrew Vasquez rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
25397f45dd0bSAndrew Vasquez (ha->r_a_tov / 10 * 2) + 2);
25401c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
25417c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1063,
25427c3df132SSaurav Kashyap "Failed to issue login IOCB (%x).\n", rval);
25431c7c6357SAndrew Vasquez } else if (lg->entry_status != 0) {
25447c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1064,
25457c3df132SSaurav Kashyap "Failed to complete IOCB -- error status (%x).\n",
25467c3df132SSaurav Kashyap lg->entry_status);
25471c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
2548ad950360SBart Van Assche } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
25491c7c6357SAndrew Vasquez iop[0] = le32_to_cpu(lg->io_parameter[0]);
25501c7c6357SAndrew Vasquez iop[1] = le32_to_cpu(lg->io_parameter[1]);
25511c7c6357SAndrew Vasquez
25527c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1065,
25537c3df132SSaurav Kashyap "Failed to complete IOCB -- completion status (%x) "
25547c3df132SSaurav Kashyap "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
25557c3df132SSaurav Kashyap iop[0], iop[1]);
25561c7c6357SAndrew Vasquez
25571c7c6357SAndrew Vasquez switch (iop[0]) {
25581c7c6357SAndrew Vasquez case LSC_SCODE_PORTID_USED:
25591c7c6357SAndrew Vasquez mb[0] = MBS_PORT_ID_USED;
25601c7c6357SAndrew Vasquez mb[1] = LSW(iop[1]);
25611c7c6357SAndrew Vasquez break;
25621c7c6357SAndrew Vasquez case LSC_SCODE_NPORT_USED:
25631c7c6357SAndrew Vasquez mb[0] = MBS_LOOP_ID_USED;
25641c7c6357SAndrew Vasquez break;
25651c7c6357SAndrew Vasquez case LSC_SCODE_NOLINK:
25661c7c6357SAndrew Vasquez case LSC_SCODE_NOIOCB:
25671c7c6357SAndrew Vasquez case LSC_SCODE_NOXCB:
25681c7c6357SAndrew Vasquez case LSC_SCODE_CMD_FAILED:
25691c7c6357SAndrew Vasquez case LSC_SCODE_NOFABRIC:
25701c7c6357SAndrew Vasquez case LSC_SCODE_FW_NOT_READY:
25711c7c6357SAndrew Vasquez case LSC_SCODE_NOT_LOGGED_IN:
25721c7c6357SAndrew Vasquez case LSC_SCODE_NOPCB:
25731c7c6357SAndrew Vasquez case LSC_SCODE_ELS_REJECT:
25741c7c6357SAndrew Vasquez case LSC_SCODE_CMD_PARAM_ERR:
25751c7c6357SAndrew Vasquez case LSC_SCODE_NONPORT:
25761c7c6357SAndrew Vasquez case LSC_SCODE_LOGGED_IN:
25771c7c6357SAndrew Vasquez case LSC_SCODE_NOFLOGI_ACC:
25781c7c6357SAndrew Vasquez default:
25791c7c6357SAndrew Vasquez mb[0] = MBS_COMMAND_ERROR;
25801c7c6357SAndrew Vasquez break;
25811c7c6357SAndrew Vasquez }
25821c7c6357SAndrew Vasquez } else {
25835f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
25845f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
25851c7c6357SAndrew Vasquez
25861c7c6357SAndrew Vasquez iop[0] = le32_to_cpu(lg->io_parameter[0]);
25871c7c6357SAndrew Vasquez
25881c7c6357SAndrew Vasquez mb[0] = MBS_COMMAND_COMPLETE;
25891c7c6357SAndrew Vasquez mb[1] = 0;
25901c7c6357SAndrew Vasquez if (iop[0] & BIT_4) {
25911c7c6357SAndrew Vasquez if (iop[0] & BIT_8)
25921c7c6357SAndrew Vasquez mb[1] |= BIT_1;
25931c7c6357SAndrew Vasquez } else
25941c7c6357SAndrew Vasquez mb[1] = BIT_0;
2595ad3e0edaSAndrew Vasquez
2596ad3e0edaSAndrew Vasquez /* Passback COS information. */
2597ad3e0edaSAndrew Vasquez mb[10] = 0;
2598ad3e0edaSAndrew Vasquez if (lg->io_parameter[7] || lg->io_parameter[8])
2599ad3e0edaSAndrew Vasquez mb[10] |= BIT_0; /* Class 2. */
2600ad3e0edaSAndrew Vasquez if (lg->io_parameter[9] || lg->io_parameter[10])
2601ad3e0edaSAndrew Vasquez mb[10] |= BIT_1; /* Class 3. */
2602ad950360SBart Van Assche if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
26032d70c103SNicholas Bellinger mb[10] |= BIT_7; /* Confirmed Completion
26042d70c103SNicholas Bellinger * Allowed
26052d70c103SNicholas Bellinger */
26061c7c6357SAndrew Vasquez }
26071c7c6357SAndrew Vasquez
26081c7c6357SAndrew Vasquez dma_pool_free(ha->s_dma_pool, lg, lg_dma);
26091c7c6357SAndrew Vasquez
26101c7c6357SAndrew Vasquez return rval;
26111c7c6357SAndrew Vasquez }
26121c7c6357SAndrew Vasquez
26131da177e4SLinus Torvalds /*
26141da177e4SLinus Torvalds * qla2x00_login_fabric
26151da177e4SLinus Torvalds * Issue login fabric port mailbox command.
26161da177e4SLinus Torvalds *
26171da177e4SLinus Torvalds * Input:
26181da177e4SLinus Torvalds * ha = adapter block pointer.
26191da177e4SLinus Torvalds * loop_id = device loop ID.
26201da177e4SLinus Torvalds * domain = device domain.
26211da177e4SLinus Torvalds * area = device area.
26221da177e4SLinus Torvalds * al_pa = device AL_PA.
26231da177e4SLinus Torvalds * status = pointer for return status.
26241da177e4SLinus Torvalds * opt = command options.
26251da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
26261da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
26271da177e4SLinus Torvalds *
26281da177e4SLinus Torvalds * Returns:
26291da177e4SLinus Torvalds * qla2x00 local function return status code.
26301da177e4SLinus Torvalds *
26311da177e4SLinus Torvalds * Context:
26321da177e4SLinus Torvalds * Kernel context.
26331da177e4SLinus Torvalds */
26341da177e4SLinus Torvalds int
qla2x00_login_fabric(scsi_qla_host_t * vha,uint16_t loop_id,uint8_t domain,uint8_t area,uint8_t al_pa,uint16_t * mb,uint8_t opt)26357b867cf7SAnirban Chakraborty qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
26361da177e4SLinus Torvalds uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
26371da177e4SLinus Torvalds {
26381da177e4SLinus Torvalds int rval;
26391da177e4SLinus Torvalds mbx_cmd_t mc;
26401da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
26417b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
26421da177e4SLinus Torvalds
26435f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
26445f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
26451da177e4SLinus Torvalds
26461da177e4SLinus Torvalds mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
26471da177e4SLinus Torvalds mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
26481da177e4SLinus Torvalds if (HAS_EXTENDED_IDS(ha)) {
26491da177e4SLinus Torvalds mcp->mb[1] = loop_id;
26501da177e4SLinus Torvalds mcp->mb[10] = opt;
26511da177e4SLinus Torvalds mcp->out_mb |= MBX_10;
26521da177e4SLinus Torvalds } else {
26531da177e4SLinus Torvalds mcp->mb[1] = (loop_id << 8) | opt;
26541da177e4SLinus Torvalds }
26551da177e4SLinus Torvalds mcp->mb[2] = domain;
26561da177e4SLinus Torvalds mcp->mb[3] = area << 8 | al_pa;
26571da177e4SLinus Torvalds
26581da177e4SLinus Torvalds mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
26591da177e4SLinus Torvalds mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
26601da177e4SLinus Torvalds mcp->flags = 0;
26617b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
26621da177e4SLinus Torvalds
26631da177e4SLinus Torvalds /* Return mailbox statuses. */
26641da177e4SLinus Torvalds if (mb != NULL) {
26651da177e4SLinus Torvalds mb[0] = mcp->mb[0];
26661da177e4SLinus Torvalds mb[1] = mcp->mb[1];
26671da177e4SLinus Torvalds mb[2] = mcp->mb[2];
26681da177e4SLinus Torvalds mb[6] = mcp->mb[6];
26691da177e4SLinus Torvalds mb[7] = mcp->mb[7];
2670ad3e0edaSAndrew Vasquez /* COS retrieved from Get-Port-Database mailbox command. */
2671ad3e0edaSAndrew Vasquez mb[10] = 0;
26721da177e4SLinus Torvalds }
26731da177e4SLinus Torvalds
26741da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
26751da177e4SLinus Torvalds /* RLU tmp code: need to change main mailbox_command function to
26761da177e4SLinus Torvalds * return ok even when the mailbox completion value is not
26771da177e4SLinus Torvalds * SUCCESS. The caller needs to be responsible to interpret
26781da177e4SLinus Torvalds * the return values of this mailbox command if we're not
26791da177e4SLinus Torvalds * to change too much of the existing code.
26801da177e4SLinus Torvalds */
26811da177e4SLinus Torvalds if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
26821da177e4SLinus Torvalds mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
26831da177e4SLinus Torvalds mcp->mb[0] == 0x4006)
26841da177e4SLinus Torvalds rval = QLA_SUCCESS;
26851da177e4SLinus Torvalds
26861da177e4SLinus Torvalds /*EMPTY*/
26877c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1068,
26887c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
26897c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
26901da177e4SLinus Torvalds } else {
26911da177e4SLinus Torvalds /*EMPTY*/
26925f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
26935f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
26941da177e4SLinus Torvalds }
26951da177e4SLinus Torvalds
26961da177e4SLinus Torvalds return rval;
26971da177e4SLinus Torvalds }
26981da177e4SLinus Torvalds
26991da177e4SLinus Torvalds /*
27001da177e4SLinus Torvalds * qla2x00_login_local_device
27011da177e4SLinus Torvalds * Issue login loop port mailbox command.
27021da177e4SLinus Torvalds *
27031da177e4SLinus Torvalds * Input:
27041da177e4SLinus Torvalds * ha = adapter block pointer.
27051da177e4SLinus Torvalds * loop_id = device loop ID.
27061da177e4SLinus Torvalds * opt = command options.
27071da177e4SLinus Torvalds *
27081da177e4SLinus Torvalds * Returns:
27091da177e4SLinus Torvalds * Return status code.
27101da177e4SLinus Torvalds *
27111da177e4SLinus Torvalds * Context:
27121da177e4SLinus Torvalds * Kernel context.
27131da177e4SLinus Torvalds *
27141da177e4SLinus Torvalds */
27151da177e4SLinus Torvalds int
qla2x00_login_local_device(scsi_qla_host_t * vha,fc_port_t * fcport,uint16_t * mb_ret,uint8_t opt)27167b867cf7SAnirban Chakraborty qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
27171da177e4SLinus Torvalds uint16_t *mb_ret, uint8_t opt)
27181da177e4SLinus Torvalds {
27191da177e4SLinus Torvalds int rval;
27201da177e4SLinus Torvalds mbx_cmd_t mc;
27211da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
27227b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
27231da177e4SLinus Torvalds
27245f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
27255f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
27267c3df132SSaurav Kashyap
2727e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha))
27287b867cf7SAnirban Chakraborty return qla24xx_login_fabric(vha, fcport->loop_id,
27299a52a57cSandrew.vasquez@qlogic.com fcport->d_id.b.domain, fcport->d_id.b.area,
27309a52a57cSandrew.vasquez@qlogic.com fcport->d_id.b.al_pa, mb_ret, opt);
27319a52a57cSandrew.vasquez@qlogic.com
27321da177e4SLinus Torvalds mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
27331da177e4SLinus Torvalds if (HAS_EXTENDED_IDS(ha))
27349a52a57cSandrew.vasquez@qlogic.com mcp->mb[1] = fcport->loop_id;
27351da177e4SLinus Torvalds else
27369a52a57cSandrew.vasquez@qlogic.com mcp->mb[1] = fcport->loop_id << 8;
27371da177e4SLinus Torvalds mcp->mb[2] = opt;
27381da177e4SLinus Torvalds mcp->out_mb = MBX_2|MBX_1|MBX_0;
27391da177e4SLinus Torvalds mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
27401da177e4SLinus Torvalds mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
27411da177e4SLinus Torvalds mcp->flags = 0;
27427b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
27431da177e4SLinus Torvalds
27441da177e4SLinus Torvalds /* Return mailbox statuses. */
27451da177e4SLinus Torvalds if (mb_ret != NULL) {
27461da177e4SLinus Torvalds mb_ret[0] = mcp->mb[0];
27471da177e4SLinus Torvalds mb_ret[1] = mcp->mb[1];
27481da177e4SLinus Torvalds mb_ret[6] = mcp->mb[6];
27491da177e4SLinus Torvalds mb_ret[7] = mcp->mb[7];
27501da177e4SLinus Torvalds }
27511da177e4SLinus Torvalds
27521da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
27531da177e4SLinus Torvalds /* AV tmp code: need to change main mailbox_command function to
27541da177e4SLinus Torvalds * return ok even when the mailbox completion value is not
27551da177e4SLinus Torvalds * SUCCESS. The caller needs to be responsible to interpret
27561da177e4SLinus Torvalds * the return values of this mailbox command if we're not
27571da177e4SLinus Torvalds * to change too much of the existing code.
27581da177e4SLinus Torvalds */
27591da177e4SLinus Torvalds if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
27601da177e4SLinus Torvalds rval = QLA_SUCCESS;
27611da177e4SLinus Torvalds
27627c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x106b,
27637c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
27647c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
27651da177e4SLinus Torvalds } else {
27661da177e4SLinus Torvalds /*EMPTY*/
27675f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
27685f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
27691da177e4SLinus Torvalds }
27701da177e4SLinus Torvalds
27711da177e4SLinus Torvalds return (rval);
27721da177e4SLinus Torvalds }
27731da177e4SLinus Torvalds
27741c7c6357SAndrew Vasquez int
qla24xx_fabric_logout(scsi_qla_host_t * vha,uint16_t loop_id,uint8_t domain,uint8_t area,uint8_t al_pa)27757b867cf7SAnirban Chakraborty qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
27761c7c6357SAndrew Vasquez uint8_t area, uint8_t al_pa)
27771c7c6357SAndrew Vasquez {
27781c7c6357SAndrew Vasquez int rval;
27791c7c6357SAndrew Vasquez struct logio_entry_24xx *lg;
27801c7c6357SAndrew Vasquez dma_addr_t lg_dma;
27817b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
27822afa19a9SAnirban Chakraborty struct req_que *req;
27831c7c6357SAndrew Vasquez
27845f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
27855f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
27861c7c6357SAndrew Vasquez
278708eb7f45SThomas Meyer lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
27881c7c6357SAndrew Vasquez if (lg == NULL) {
27897c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x106e,
27907c3df132SSaurav Kashyap "Failed to allocate logout IOCB.\n");
27911c7c6357SAndrew Vasquez return QLA_MEMORY_ALLOC_FAILED;
27921c7c6357SAndrew Vasquez }
27931c7c6357SAndrew Vasquez
27942afa19a9SAnirban Chakraborty req = vha->req;
27951c7c6357SAndrew Vasquez lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
27961c7c6357SAndrew Vasquez lg->entry_count = 1;
2797c25eb70aSBart Van Assche lg->handle = make_handle(req->id, lg->handle);
27981c7c6357SAndrew Vasquez lg->nport_handle = cpu_to_le16(loop_id);
27991c7c6357SAndrew Vasquez lg->control_flags =
2800ad950360SBart Van Assche cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
2801c8d6691bSAndrew Vasquez LCF_FREE_NPORT);
28021c7c6357SAndrew Vasquez lg->port_id[0] = al_pa;
28031c7c6357SAndrew Vasquez lg->port_id[1] = area;
28041c7c6357SAndrew Vasquez lg->port_id[2] = domain;
28057b867cf7SAnirban Chakraborty lg->vp_index = vha->vp_idx;
28067f45dd0bSAndrew Vasquez rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
28077f45dd0bSAndrew Vasquez (ha->r_a_tov / 10 * 2) + 2);
28081c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
28097c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x106f,
28107c3df132SSaurav Kashyap "Failed to issue logout IOCB (%x).\n", rval);
28111c7c6357SAndrew Vasquez } else if (lg->entry_status != 0) {
28127c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1070,
28137c3df132SSaurav Kashyap "Failed to complete IOCB -- error status (%x).\n",
28147c3df132SSaurav Kashyap lg->entry_status);
28151c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
2816ad950360SBart Van Assche } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
28177c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1071,
28187c3df132SSaurav Kashyap "Failed to complete IOCB -- completion status (%x) "
28197c3df132SSaurav Kashyap "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
28201c7c6357SAndrew Vasquez le32_to_cpu(lg->io_parameter[0]),
28217c3df132SSaurav Kashyap le32_to_cpu(lg->io_parameter[1]));
28221c7c6357SAndrew Vasquez } else {
28231c7c6357SAndrew Vasquez /*EMPTY*/
28245f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
28255f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
28261c7c6357SAndrew Vasquez }
28271c7c6357SAndrew Vasquez
28281c7c6357SAndrew Vasquez dma_pool_free(ha->s_dma_pool, lg, lg_dma);
28291c7c6357SAndrew Vasquez
28301c7c6357SAndrew Vasquez return rval;
28311c7c6357SAndrew Vasquez }
28321c7c6357SAndrew Vasquez
28331da177e4SLinus Torvalds /*
28341da177e4SLinus Torvalds * qla2x00_fabric_logout
28351da177e4SLinus Torvalds * Issue logout fabric port mailbox command.
28361da177e4SLinus Torvalds *
28371da177e4SLinus Torvalds * Input:
28381da177e4SLinus Torvalds * ha = adapter block pointer.
28391da177e4SLinus Torvalds * loop_id = device loop ID.
28401da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
28411da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
28421da177e4SLinus Torvalds *
28431da177e4SLinus Torvalds * Returns:
28441da177e4SLinus Torvalds * qla2x00 local function return status code.
28451da177e4SLinus Torvalds *
28461da177e4SLinus Torvalds * Context:
28471da177e4SLinus Torvalds * Kernel context.
28481da177e4SLinus Torvalds */
28491da177e4SLinus Torvalds int
qla2x00_fabric_logout(scsi_qla_host_t * vha,uint16_t loop_id,uint8_t domain,uint8_t area,uint8_t al_pa)28507b867cf7SAnirban Chakraborty qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
28511c7c6357SAndrew Vasquez uint8_t area, uint8_t al_pa)
28521da177e4SLinus Torvalds {
28531da177e4SLinus Torvalds int rval;
28541da177e4SLinus Torvalds mbx_cmd_t mc;
28551da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
28561da177e4SLinus Torvalds
28575f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
28585f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
28591da177e4SLinus Torvalds
28601da177e4SLinus Torvalds mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
28611da177e4SLinus Torvalds mcp->out_mb = MBX_1|MBX_0;
28627b867cf7SAnirban Chakraborty if (HAS_EXTENDED_IDS(vha->hw)) {
28631da177e4SLinus Torvalds mcp->mb[1] = loop_id;
28641da177e4SLinus Torvalds mcp->mb[10] = 0;
28651da177e4SLinus Torvalds mcp->out_mb |= MBX_10;
28661da177e4SLinus Torvalds } else {
28671da177e4SLinus Torvalds mcp->mb[1] = loop_id << 8;
28681da177e4SLinus Torvalds }
28691da177e4SLinus Torvalds
28701da177e4SLinus Torvalds mcp->in_mb = MBX_1|MBX_0;
2871b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
28721da177e4SLinus Torvalds mcp->flags = 0;
28737b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
28741da177e4SLinus Torvalds
28751da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
28761da177e4SLinus Torvalds /*EMPTY*/
28777c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1074,
28787c3df132SSaurav Kashyap "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
28791da177e4SLinus Torvalds } else {
28801da177e4SLinus Torvalds /*EMPTY*/
28815f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
28825f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
28831da177e4SLinus Torvalds }
28841da177e4SLinus Torvalds
28851da177e4SLinus Torvalds return rval;
28861da177e4SLinus Torvalds }
28871da177e4SLinus Torvalds
28881da177e4SLinus Torvalds /*
28891da177e4SLinus Torvalds * qla2x00_full_login_lip
28901da177e4SLinus Torvalds * Issue full login LIP mailbox command.
28911da177e4SLinus Torvalds *
28921da177e4SLinus Torvalds * Input:
28931da177e4SLinus Torvalds * ha = adapter block pointer.
28941da177e4SLinus Torvalds * TARGET_QUEUE_LOCK must be released.
28951da177e4SLinus Torvalds * ADAPTER_STATE_LOCK must be released.
28961da177e4SLinus Torvalds *
28971da177e4SLinus Torvalds * Returns:
28981da177e4SLinus Torvalds * qla2x00 local function return status code.
28991da177e4SLinus Torvalds *
29001da177e4SLinus Torvalds * Context:
29011da177e4SLinus Torvalds * Kernel context.
29021da177e4SLinus Torvalds */
29031da177e4SLinus Torvalds int
qla2x00_full_login_lip(scsi_qla_host_t * vha)29047b867cf7SAnirban Chakraborty qla2x00_full_login_lip(scsi_qla_host_t *vha)
29051da177e4SLinus Torvalds {
29061da177e4SLinus Torvalds int rval;
29071da177e4SLinus Torvalds mbx_cmd_t mc;
29081da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
29091da177e4SLinus Torvalds
29105f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
29115f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
29121da177e4SLinus Torvalds
29131da177e4SLinus Torvalds mcp->mb[0] = MBC_LIP_FULL_LOGIN;
291487d6814aSQuinn Tran mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_4 : 0;
29150c8c39afSAndrew Vasquez mcp->mb[2] = 0;
29161da177e4SLinus Torvalds mcp->mb[3] = 0;
29171da177e4SLinus Torvalds mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
29181da177e4SLinus Torvalds mcp->in_mb = MBX_0;
2919b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
29201da177e4SLinus Torvalds mcp->flags = 0;
29217b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
29221da177e4SLinus Torvalds
29231da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
29241da177e4SLinus Torvalds /*EMPTY*/
29257c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
29261da177e4SLinus Torvalds } else {
29271da177e4SLinus Torvalds /*EMPTY*/
29285f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
29295f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
29301da177e4SLinus Torvalds }
29311da177e4SLinus Torvalds
29321da177e4SLinus Torvalds return rval;
29331da177e4SLinus Torvalds }
29341da177e4SLinus Torvalds
29351da177e4SLinus Torvalds /*
29361da177e4SLinus Torvalds * qla2x00_get_id_list
29371da177e4SLinus Torvalds *
29381da177e4SLinus Torvalds * Input:
29391da177e4SLinus Torvalds * ha = adapter block pointer.
29401da177e4SLinus Torvalds *
29411da177e4SLinus Torvalds * Returns:
29421da177e4SLinus Torvalds * qla2x00 local function return status code.
29431da177e4SLinus Torvalds *
29441da177e4SLinus Torvalds * Context:
29451da177e4SLinus Torvalds * Kernel context.
29461da177e4SLinus Torvalds */
29471da177e4SLinus Torvalds int
qla2x00_get_id_list(scsi_qla_host_t * vha,void * id_list,dma_addr_t id_list_dma,uint16_t * entries)29487b867cf7SAnirban Chakraborty qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
29491da177e4SLinus Torvalds uint16_t *entries)
29501da177e4SLinus Torvalds {
29511da177e4SLinus Torvalds int rval;
29521da177e4SLinus Torvalds mbx_cmd_t mc;
29531da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
29541da177e4SLinus Torvalds
29555f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
29565f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
29571da177e4SLinus Torvalds
29581da177e4SLinus Torvalds if (id_list == NULL)
29591da177e4SLinus Torvalds return QLA_FUNCTION_FAILED;
29601da177e4SLinus Torvalds
29611da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_ID_LIST;
29621c7c6357SAndrew Vasquez mcp->out_mb = MBX_0;
29637b867cf7SAnirban Chakraborty if (IS_FWI2_CAPABLE(vha->hw)) {
29641c7c6357SAndrew Vasquez mcp->mb[2] = MSW(id_list_dma);
29651c7c6357SAndrew Vasquez mcp->mb[3] = LSW(id_list_dma);
29661c7c6357SAndrew Vasquez mcp->mb[6] = MSW(MSD(id_list_dma));
29671c7c6357SAndrew Vasquez mcp->mb[7] = LSW(MSD(id_list_dma));
2968247ec457Sandrew.vasquez@qlogic.com mcp->mb[8] = 0;
29697b867cf7SAnirban Chakraborty mcp->mb[9] = vha->vp_idx;
29702c3dfe3fSSeokmann Ju mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
29711c7c6357SAndrew Vasquez } else {
29721da177e4SLinus Torvalds mcp->mb[1] = MSW(id_list_dma);
29731da177e4SLinus Torvalds mcp->mb[2] = LSW(id_list_dma);
29741da177e4SLinus Torvalds mcp->mb[3] = MSW(MSD(id_list_dma));
29751da177e4SLinus Torvalds mcp->mb[6] = LSW(MSD(id_list_dma));
29761c7c6357SAndrew Vasquez mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
29771c7c6357SAndrew Vasquez }
29781da177e4SLinus Torvalds mcp->in_mb = MBX_1|MBX_0;
2979b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
29801da177e4SLinus Torvalds mcp->flags = 0;
29817b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
29821da177e4SLinus Torvalds
29831da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
29841da177e4SLinus Torvalds /*EMPTY*/
29857c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
29861da177e4SLinus Torvalds } else {
29871da177e4SLinus Torvalds *entries = mcp->mb[1];
29885f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
29895f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
29901da177e4SLinus Torvalds }
29911da177e4SLinus Torvalds
29921da177e4SLinus Torvalds return rval;
29931da177e4SLinus Torvalds }
29941da177e4SLinus Torvalds
29951da177e4SLinus Torvalds /*
29961da177e4SLinus Torvalds * qla2x00_get_resource_cnts
29971da177e4SLinus Torvalds * Get current firmware resource counts.
29981da177e4SLinus Torvalds *
29991da177e4SLinus Torvalds * Input:
30001da177e4SLinus Torvalds * ha = adapter block pointer.
30011da177e4SLinus Torvalds *
30021da177e4SLinus Torvalds * Returns:
30031da177e4SLinus Torvalds * qla2x00 local function return status code.
30041da177e4SLinus Torvalds *
30051da177e4SLinus Torvalds * Context:
30061da177e4SLinus Torvalds * Kernel context.
30071da177e4SLinus Torvalds */
30081da177e4SLinus Torvalds int
qla2x00_get_resource_cnts(scsi_qla_host_t * vha)300903e8c680SQuinn Tran qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
30101da177e4SLinus Torvalds {
301103e8c680SQuinn Tran struct qla_hw_data *ha = vha->hw;
30121da177e4SLinus Torvalds int rval;
30131da177e4SLinus Torvalds mbx_cmd_t mc;
30141da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
30151da177e4SLinus Torvalds
30165f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
30175f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
30181da177e4SLinus Torvalds
30191da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
30201da177e4SLinus Torvalds mcp->out_mb = MBX_0;
30214d0ea247SSeokmann Ju mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3022ecc89f25SJoe Carnuccio if (IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
3023ecc89f25SJoe Carnuccio IS_QLA27XX(ha) || IS_QLA28XX(ha))
3024f3a0a77eSAndrew Vasquez mcp->in_mb |= MBX_12;
3025b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
30261da177e4SLinus Torvalds mcp->flags = 0;
30277b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
30281da177e4SLinus Torvalds
30291da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
30301da177e4SLinus Torvalds /*EMPTY*/
30317c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x107d,
30327c3df132SSaurav Kashyap "Failed mb[0]=%x.\n", mcp->mb[0]);
30331da177e4SLinus Torvalds } else {
30345f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
30357c3df132SSaurav Kashyap "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
30367c3df132SSaurav Kashyap "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
30377c3df132SSaurav Kashyap mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
30387c3df132SSaurav Kashyap mcp->mb[11], mcp->mb[12]);
30391da177e4SLinus Torvalds
304003e8c680SQuinn Tran ha->orig_fw_tgt_xcb_count = mcp->mb[1];
304103e8c680SQuinn Tran ha->cur_fw_tgt_xcb_count = mcp->mb[2];
304203e8c680SQuinn Tran ha->cur_fw_xcb_count = mcp->mb[3];
304303e8c680SQuinn Tran ha->orig_fw_xcb_count = mcp->mb[6];
304403e8c680SQuinn Tran ha->cur_fw_iocb_count = mcp->mb[7];
304503e8c680SQuinn Tran ha->orig_fw_iocb_count = mcp->mb[10];
304603e8c680SQuinn Tran if (ha->flags.npiv_supported)
304703e8c680SQuinn Tran ha->max_npiv_vports = mcp->mb[11];
30480d6a536cSJoe Carnuccio if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
304903e8c680SQuinn Tran ha->fw_max_fcf_count = mcp->mb[12];
30501da177e4SLinus Torvalds }
30511da177e4SLinus Torvalds
30521da177e4SLinus Torvalds return (rval);
30531da177e4SLinus Torvalds }
30541da177e4SLinus Torvalds
30551da177e4SLinus Torvalds /*
30561da177e4SLinus Torvalds * qla2x00_get_fcal_position_map
30571da177e4SLinus Torvalds * Get FCAL (LILP) position map using mailbox command
30581da177e4SLinus Torvalds *
30591da177e4SLinus Torvalds * Input:
30601da177e4SLinus Torvalds * ha = adapter state pointer.
30611da177e4SLinus Torvalds * pos_map = buffer pointer (can be NULL).
30621da177e4SLinus Torvalds *
30631da177e4SLinus Torvalds * Returns:
30641da177e4SLinus Torvalds * qla2x00 local function return status code.
30651da177e4SLinus Torvalds *
30661da177e4SLinus Torvalds * Context:
30671da177e4SLinus Torvalds * Kernel context.
30681da177e4SLinus Torvalds */
30691da177e4SLinus Torvalds int
qla2x00_get_fcal_position_map(scsi_qla_host_t * vha,char * pos_map,u8 * num_entries)307047ccb113SArun Easi qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map,
307147ccb113SArun Easi u8 *num_entries)
30721da177e4SLinus Torvalds {
30731da177e4SLinus Torvalds int rval;
30741da177e4SLinus Torvalds mbx_cmd_t mc;
30751da177e4SLinus Torvalds mbx_cmd_t *mcp = &mc;
30761da177e4SLinus Torvalds char *pmap;
30771da177e4SLinus Torvalds dma_addr_t pmap_dma;
30787b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
30791da177e4SLinus Torvalds
30805f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
30815f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
30827c3df132SSaurav Kashyap
308308eb7f45SThomas Meyer pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
30841da177e4SLinus Torvalds if (pmap == NULL) {
30857c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x1080,
30867c3df132SSaurav Kashyap "Memory alloc failed.\n");
30871da177e4SLinus Torvalds return QLA_MEMORY_ALLOC_FAILED;
30881da177e4SLinus Torvalds }
30891da177e4SLinus Torvalds
30901da177e4SLinus Torvalds mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
30911da177e4SLinus Torvalds mcp->mb[2] = MSW(pmap_dma);
30921da177e4SLinus Torvalds mcp->mb[3] = LSW(pmap_dma);
30931da177e4SLinus Torvalds mcp->mb[6] = MSW(MSD(pmap_dma));
30941da177e4SLinus Torvalds mcp->mb[7] = LSW(MSD(pmap_dma));
30951da177e4SLinus Torvalds mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
30961da177e4SLinus Torvalds mcp->in_mb = MBX_1|MBX_0;
30971da177e4SLinus Torvalds mcp->buf_size = FCAL_MAP_SIZE;
30981da177e4SLinus Torvalds mcp->flags = MBX_DMA_IN;
30991da177e4SLinus Torvalds mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
31007b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
31011da177e4SLinus Torvalds
31021da177e4SLinus Torvalds if (rval == QLA_SUCCESS) {
31035f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
31047c3df132SSaurav Kashyap "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
31057c3df132SSaurav Kashyap mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
31067c3df132SSaurav Kashyap ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
31077c3df132SSaurav Kashyap pmap, pmap[0] + 1);
31081da177e4SLinus Torvalds
31091da177e4SLinus Torvalds if (pos_map)
31101da177e4SLinus Torvalds memcpy(pos_map, pmap, FCAL_MAP_SIZE);
311147ccb113SArun Easi if (num_entries)
311247ccb113SArun Easi *num_entries = pmap[0];
31131da177e4SLinus Torvalds }
31141da177e4SLinus Torvalds dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
31151da177e4SLinus Torvalds
31161da177e4SLinus Torvalds if (rval != QLA_SUCCESS) {
31177c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
31181da177e4SLinus Torvalds } else {
31195f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
31205f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
31211da177e4SLinus Torvalds }
31221da177e4SLinus Torvalds
31231da177e4SLinus Torvalds return rval;
31241da177e4SLinus Torvalds }
31251c7c6357SAndrew Vasquez
3126392e2f65Sandrew.vasquez@qlogic.com /*
3127392e2f65Sandrew.vasquez@qlogic.com * qla2x00_get_link_status
3128392e2f65Sandrew.vasquez@qlogic.com *
3129392e2f65Sandrew.vasquez@qlogic.com * Input:
3130392e2f65Sandrew.vasquez@qlogic.com * ha = adapter block pointer.
3131392e2f65Sandrew.vasquez@qlogic.com * loop_id = device loop ID.
3132392e2f65Sandrew.vasquez@qlogic.com * ret_buf = pointer to link status return buffer.
3133392e2f65Sandrew.vasquez@qlogic.com *
3134392e2f65Sandrew.vasquez@qlogic.com * Returns:
3135392e2f65Sandrew.vasquez@qlogic.com * 0 = success.
3136392e2f65Sandrew.vasquez@qlogic.com * BIT_0 = mem alloc error.
3137392e2f65Sandrew.vasquez@qlogic.com * BIT_1 = mailbox error.
3138392e2f65Sandrew.vasquez@qlogic.com */
3139392e2f65Sandrew.vasquez@qlogic.com int
qla2x00_get_link_status(scsi_qla_host_t * vha,uint16_t loop_id,struct link_statistics * stats,dma_addr_t stats_dma)31407b867cf7SAnirban Chakraborty qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
314143ef0580SAndrew Vasquez struct link_statistics *stats, dma_addr_t stats_dma)
3142392e2f65Sandrew.vasquez@qlogic.com {
3143392e2f65Sandrew.vasquez@qlogic.com int rval;
3144392e2f65Sandrew.vasquez@qlogic.com mbx_cmd_t mc;
3145392e2f65Sandrew.vasquez@qlogic.com mbx_cmd_t *mcp = &mc;
3146ab053c09SBart Van Assche uint32_t *iter = (uint32_t *)stats;
3147c6dc9905SJoe Carnuccio ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);
31487b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
3149392e2f65Sandrew.vasquez@qlogic.com
31505f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
31515f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
3152392e2f65Sandrew.vasquez@qlogic.com
3153392e2f65Sandrew.vasquez@qlogic.com mcp->mb[0] = MBC_GET_LINK_STATUS;
3154c6dc9905SJoe Carnuccio mcp->mb[2] = MSW(LSD(stats_dma));
3155c6dc9905SJoe Carnuccio mcp->mb[3] = LSW(LSD(stats_dma));
315643ef0580SAndrew Vasquez mcp->mb[6] = MSW(MSD(stats_dma));
315743ef0580SAndrew Vasquez mcp->mb[7] = LSW(MSD(stats_dma));
3158392e2f65Sandrew.vasquez@qlogic.com mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3159392e2f65Sandrew.vasquez@qlogic.com mcp->in_mb = MBX_0;
3160e428924cSAndrew Vasquez if (IS_FWI2_CAPABLE(ha)) {
3161392e2f65Sandrew.vasquez@qlogic.com mcp->mb[1] = loop_id;
3162392e2f65Sandrew.vasquez@qlogic.com mcp->mb[4] = 0;
3163392e2f65Sandrew.vasquez@qlogic.com mcp->mb[10] = 0;
3164392e2f65Sandrew.vasquez@qlogic.com mcp->out_mb |= MBX_10|MBX_4|MBX_1;
3165392e2f65Sandrew.vasquez@qlogic.com mcp->in_mb |= MBX_1;
3166392e2f65Sandrew.vasquez@qlogic.com } else if (HAS_EXTENDED_IDS(ha)) {
3167392e2f65Sandrew.vasquez@qlogic.com mcp->mb[1] = loop_id;
3168392e2f65Sandrew.vasquez@qlogic.com mcp->mb[10] = 0;
3169392e2f65Sandrew.vasquez@qlogic.com mcp->out_mb |= MBX_10|MBX_1;
3170392e2f65Sandrew.vasquez@qlogic.com } else {
3171392e2f65Sandrew.vasquez@qlogic.com mcp->mb[1] = loop_id << 8;
3172392e2f65Sandrew.vasquez@qlogic.com mcp->out_mb |= MBX_1;
3173392e2f65Sandrew.vasquez@qlogic.com }
3174b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
3175392e2f65Sandrew.vasquez@qlogic.com mcp->flags = IOCTL_CMD;
31767b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3177392e2f65Sandrew.vasquez@qlogic.com
3178392e2f65Sandrew.vasquez@qlogic.com if (rval == QLA_SUCCESS) {
3179392e2f65Sandrew.vasquez@qlogic.com if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
31807c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1085,
31817c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
318243ef0580SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
3183392e2f65Sandrew.vasquez@qlogic.com } else {
3184c6dc9905SJoe Carnuccio /* Re-endianize - firmware data is le32. */
31855f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
31865f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3187da08ef5cSJoe Carnuccio for ( ; dwords--; iter++)
3188da08ef5cSJoe Carnuccio le32_to_cpus(iter);
3189392e2f65Sandrew.vasquez@qlogic.com }
3190392e2f65Sandrew.vasquez@qlogic.com } else {
3191392e2f65Sandrew.vasquez@qlogic.com /* Failed. */
31927c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
3193392e2f65Sandrew.vasquez@qlogic.com }
3194392e2f65Sandrew.vasquez@qlogic.com
3195392e2f65Sandrew.vasquez@qlogic.com return rval;
3196392e2f65Sandrew.vasquez@qlogic.com }
3197392e2f65Sandrew.vasquez@qlogic.com
3198392e2f65Sandrew.vasquez@qlogic.com int
qla24xx_get_isp_stats(scsi_qla_host_t * vha,struct link_statistics * stats,dma_addr_t stats_dma,uint16_t options)31997b867cf7SAnirban Chakraborty qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
320015f30a57SQuinn Tran dma_addr_t stats_dma, uint16_t options)
32011c7c6357SAndrew Vasquez {
32021c7c6357SAndrew Vasquez int rval;
32031c7c6357SAndrew Vasquez mbx_cmd_t mc;
32041c7c6357SAndrew Vasquez mbx_cmd_t *mcp = &mc;
3205ab053c09SBart Van Assche uint32_t *iter = (uint32_t *)stats;
3206818c7f87SJoe Carnuccio ushort dwords = sizeof(*stats)/sizeof(*iter);
32071c7c6357SAndrew Vasquez
32085f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
32095f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
32101c7c6357SAndrew Vasquez
321115f30a57SQuinn Tran memset(&mc, 0, sizeof(mc));
321215f30a57SQuinn Tran mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
3213818c7f87SJoe Carnuccio mc.mb[2] = MSW(LSD(stats_dma));
3214818c7f87SJoe Carnuccio mc.mb[3] = LSW(LSD(stats_dma));
321515f30a57SQuinn Tran mc.mb[6] = MSW(MSD(stats_dma));
321615f30a57SQuinn Tran mc.mb[7] = LSW(MSD(stats_dma));
3217818c7f87SJoe Carnuccio mc.mb[8] = dwords;
32187ffa5b93SBart Van Assche mc.mb[9] = vha->vp_idx;
32197ffa5b93SBart Van Assche mc.mb[10] = options;
322015f30a57SQuinn Tran
322115f30a57SQuinn Tran rval = qla24xx_send_mb_cmd(vha, &mc);
32221c7c6357SAndrew Vasquez
32231c7c6357SAndrew Vasquez if (rval == QLA_SUCCESS) {
32241c7c6357SAndrew Vasquez if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
32257c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1089,
32267c3df132SSaurav Kashyap "Failed mb[0]=%x.\n", mcp->mb[0]);
322743ef0580SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
32281c7c6357SAndrew Vasquez } else {
32295f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
32305f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3231c6dc9905SJoe Carnuccio /* Re-endianize - firmware data is le32. */
3232da08ef5cSJoe Carnuccio for ( ; dwords--; iter++)
3233da08ef5cSJoe Carnuccio le32_to_cpus(iter);
32341c7c6357SAndrew Vasquez }
32351c7c6357SAndrew Vasquez } else {
32361c7c6357SAndrew Vasquez /* Failed. */
32377c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
32381c7c6357SAndrew Vasquez }
32391c7c6357SAndrew Vasquez
32401c7c6357SAndrew Vasquez return rval;
32411c7c6357SAndrew Vasquez }
32421c7c6357SAndrew Vasquez
32431c7c6357SAndrew Vasquez int
qla24xx_abort_command(srb_t * sp)32442afa19a9SAnirban Chakraborty qla24xx_abort_command(srb_t *sp)
32451c7c6357SAndrew Vasquez {
32461c7c6357SAndrew Vasquez int rval;
32471c7c6357SAndrew Vasquez unsigned long flags = 0;
32481c7c6357SAndrew Vasquez
32491c7c6357SAndrew Vasquez struct abort_entry_24xx *abt;
32501c7c6357SAndrew Vasquez dma_addr_t abt_dma;
32511c7c6357SAndrew Vasquez uint32_t handle;
32522afa19a9SAnirban Chakraborty fc_port_t *fcport = sp->fcport;
32532afa19a9SAnirban Chakraborty struct scsi_qla_host *vha = fcport->vha;
32547b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
3255914418f3SColin Ian King struct req_que *req;
3256585def9bSQuinn Tran struct qla_qpair *qpair = sp->qpair;
32571c7c6357SAndrew Vasquez
32585f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
32595f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
32601c7c6357SAndrew Vasquez
326145a76264SArun Easi if (sp->qpair)
3262d7459527SMichael Hernandez req = sp->qpair->req;
3263585def9bSQuinn Tran else
32642cabf10dSArun Easi return QLA_ERR_NO_QPAIR;
3265d7459527SMichael Hernandez
32664440e46dSArmen Baloyan if (ql2xasynctmfenable)
32674440e46dSArmen Baloyan return qla24xx_async_abort_command(sp);
32684440e46dSArmen Baloyan
3269585def9bSQuinn Tran spin_lock_irqsave(qpair->qp_lock_ptr, flags);
32708d93f550SChad Dupuis for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
32717b867cf7SAnirban Chakraborty if (req->outstanding_cmds[handle] == sp)
32721c7c6357SAndrew Vasquez break;
32731c7c6357SAndrew Vasquez }
3274585def9bSQuinn Tran spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
32758d93f550SChad Dupuis if (handle == req->num_outstanding_cmds) {
32761c7c6357SAndrew Vasquez /* Command not found. */
32772cabf10dSArun Easi return QLA_ERR_NOT_FOUND;
32781c7c6357SAndrew Vasquez }
32791c7c6357SAndrew Vasquez
328008eb7f45SThomas Meyer abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
32811c7c6357SAndrew Vasquez if (abt == NULL) {
32827c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x108d,
32837c3df132SSaurav Kashyap "Failed to allocate abort IOCB.\n");
32841c7c6357SAndrew Vasquez return QLA_MEMORY_ALLOC_FAILED;
32851c7c6357SAndrew Vasquez }
32861c7c6357SAndrew Vasquez
32871c7c6357SAndrew Vasquez abt->entry_type = ABORT_IOCB_TYPE;
32881c7c6357SAndrew Vasquez abt->entry_count = 1;
3289c25eb70aSBart Van Assche abt->handle = make_handle(req->id, abt->handle);
32901c7c6357SAndrew Vasquez abt->nport_handle = cpu_to_le16(fcport->loop_id);
3291c25eb70aSBart Van Assche abt->handle_to_abort = make_handle(req->id, handle);
32921c7c6357SAndrew Vasquez abt->port_id[0] = fcport->d_id.b.al_pa;
32931c7c6357SAndrew Vasquez abt->port_id[1] = fcport->d_id.b.area;
32941c7c6357SAndrew Vasquez abt->port_id[2] = fcport->d_id.b.domain;
3295c6d39e23SJoe Carnuccio abt->vp_index = fcport->vha->vp_idx;
329673208dfdSAnirban Chakraborty
329773208dfdSAnirban Chakraborty abt->req_que_no = cpu_to_le16(req->id);
3298a0465859SBikash Hazarika /* Need to pass original sp */
3299a0465859SBikash Hazarika qla_nvme_abort_set_option(abt, sp);
330073208dfdSAnirban Chakraborty
33017b867cf7SAnirban Chakraborty rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
33021c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
33037c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x108e,
33047c3df132SSaurav Kashyap "Failed to issue IOCB (%x).\n", rval);
33051c7c6357SAndrew Vasquez } else if (abt->entry_status != 0) {
33067c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x108f,
33077c3df132SSaurav Kashyap "Failed to complete IOCB -- error status (%x).\n",
33087c3df132SSaurav Kashyap abt->entry_status);
33091c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
3310ad950360SBart Van Assche } else if (abt->nport_handle != cpu_to_le16(0)) {
33117c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1090,
33127c3df132SSaurav Kashyap "Failed to complete IOCB -- completion status (%x).\n",
33137c3df132SSaurav Kashyap le16_to_cpu(abt->nport_handle));
33147ffa5b93SBart Van Assche if (abt->nport_handle == cpu_to_le16(CS_IOCB_ERROR))
3315f934c9d0SChad Dupuis rval = QLA_FUNCTION_PARAMETER_ERROR;
3316f934c9d0SChad Dupuis else
33171c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
33181c7c6357SAndrew Vasquez } else {
33195f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
33205f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
33211c7c6357SAndrew Vasquez }
3322a0465859SBikash Hazarika if (rval == QLA_SUCCESS)
3323a0465859SBikash Hazarika qla_nvme_abort_process_comp_status(abt, sp);
3324a0465859SBikash Hazarika
3325a0465859SBikash Hazarika qla_wait_nvme_release_cmd_kref(sp);
33261c7c6357SAndrew Vasquez
33271c7c6357SAndrew Vasquez dma_pool_free(ha->s_dma_pool, abt, abt_dma);
33281c7c6357SAndrew Vasquez
33291c7c6357SAndrew Vasquez return rval;
33301c7c6357SAndrew Vasquez }
33311c7c6357SAndrew Vasquez
33321c7c6357SAndrew Vasquez struct tsk_mgmt_cmd {
33331c7c6357SAndrew Vasquez union {
33341c7c6357SAndrew Vasquez struct tsk_mgmt_entry tsk;
33351c7c6357SAndrew Vasquez struct sts_entry_24xx sts;
33361c7c6357SAndrew Vasquez } p;
33371c7c6357SAndrew Vasquez };
33381c7c6357SAndrew Vasquez
3339523ec773SAndrew Vasquez static int
__qla24xx_issue_tmf(char * name,uint32_t type,struct fc_port * fcport,uint64_t l,int tag)3340523ec773SAndrew Vasquez __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
33419cb78c16SHannes Reinecke uint64_t l, int tag)
33421c7c6357SAndrew Vasquez {
3343523ec773SAndrew Vasquez int rval, rval2;
33441c7c6357SAndrew Vasquez struct tsk_mgmt_cmd *tsk;
33459ca1d01fSAndrew Vasquez struct sts_entry_24xx *sts;
33461c7c6357SAndrew Vasquez dma_addr_t tsk_dma;
33477b867cf7SAnirban Chakraborty scsi_qla_host_t *vha;
33487b867cf7SAnirban Chakraborty struct qla_hw_data *ha;
334973208dfdSAnirban Chakraborty struct req_que *req;
3350d7459527SMichael Hernandez struct qla_qpair *qpair;
33511c7c6357SAndrew Vasquez
33527b867cf7SAnirban Chakraborty vha = fcport->vha;
33537b867cf7SAnirban Chakraborty ha = vha->hw;
33542afa19a9SAnirban Chakraborty req = vha->req;
33557c3df132SSaurav Kashyap
33565f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
33575f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
33587c3df132SSaurav Kashyap
3359d7459527SMichael Hernandez if (vha->vp_idx && vha->qpair) {
3360d7459527SMichael Hernandez /* NPIV port */
3361d7459527SMichael Hernandez qpair = vha->qpair;
3362d7459527SMichael Hernandez req = qpair->req;
3363d7459527SMichael Hernandez }
3364d7459527SMichael Hernandez
336508eb7f45SThomas Meyer tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
33661c7c6357SAndrew Vasquez if (tsk == NULL) {
33677c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x1093,
33687c3df132SSaurav Kashyap "Failed to allocate task management IOCB.\n");
33691c7c6357SAndrew Vasquez return QLA_MEMORY_ALLOC_FAILED;
33701c7c6357SAndrew Vasquez }
33711c7c6357SAndrew Vasquez
33721c7c6357SAndrew Vasquez tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
33731c7c6357SAndrew Vasquez tsk->p.tsk.entry_count = 1;
3374c25eb70aSBart Van Assche tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle);
33751c7c6357SAndrew Vasquez tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
337600a537b8SAndrew Vasquez tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
3377523ec773SAndrew Vasquez tsk->p.tsk.control_flags = cpu_to_le32(type);
33781c7c6357SAndrew Vasquez tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
33791c7c6357SAndrew Vasquez tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
33801c7c6357SAndrew Vasquez tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
3381c6d39e23SJoe Carnuccio tsk->p.tsk.vp_index = fcport->vha->vp_idx;
3382523ec773SAndrew Vasquez if (type == TCF_LUN_RESET) {
3383523ec773SAndrew Vasquez int_to_scsilun(l, &tsk->p.tsk.lun);
3384523ec773SAndrew Vasquez host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
3385523ec773SAndrew Vasquez sizeof(tsk->p.tsk.lun));
3386523ec773SAndrew Vasquez }
33872c3dfe3fSSeokmann Ju
33889ca1d01fSAndrew Vasquez sts = &tsk->p.sts;
33897b867cf7SAnirban Chakraborty rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
33901c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
33917c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1094,
33927c3df132SSaurav Kashyap "Failed to issue %s reset IOCB (%x).\n", name, rval);
33939ca1d01fSAndrew Vasquez } else if (sts->entry_status != 0) {
33947c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1095,
33957c3df132SSaurav Kashyap "Failed to complete IOCB -- error status (%x).\n",
33967c3df132SSaurav Kashyap sts->entry_status);
33971c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
3398ad950360SBart Van Assche } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
33997c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1096,
34007c3df132SSaurav Kashyap "Failed to complete IOCB -- completion status (%x).\n",
34017c3df132SSaurav Kashyap le16_to_cpu(sts->comp_status));
34029ca1d01fSAndrew Vasquez rval = QLA_FUNCTION_FAILED;
340397dec564SAndrew Vasquez } else if (le16_to_cpu(sts->scsi_status) &
340497dec564SAndrew Vasquez SS_RESPONSE_INFO_LEN_VALID) {
340597dec564SAndrew Vasquez if (le32_to_cpu(sts->rsp_data_len) < 4) {
34065f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
34077c3df132SSaurav Kashyap "Ignoring inconsistent data length -- not enough "
34087c3df132SSaurav Kashyap "response info (%d).\n",
34097c3df132SSaurav Kashyap le32_to_cpu(sts->rsp_data_len));
34109ca1d01fSAndrew Vasquez } else if (sts->data[3]) {
34117c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1098,
34127c3df132SSaurav Kashyap "Failed to complete IOCB -- response (%x).\n",
34137c3df132SSaurav Kashyap sts->data[3]);
34141c7c6357SAndrew Vasquez rval = QLA_FUNCTION_FAILED;
34151c7c6357SAndrew Vasquez }
341697dec564SAndrew Vasquez }
34171c7c6357SAndrew Vasquez
34181c7c6357SAndrew Vasquez /* Issue marker IOCB. */
34199eb9c6dcSQuinn Tran rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l,
3420523ec773SAndrew Vasquez type == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
3421523ec773SAndrew Vasquez if (rval2 != QLA_SUCCESS) {
34227c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1099,
34237c3df132SSaurav Kashyap "Failed to issue marker IOCB (%x).\n", rval2);
34241c7c6357SAndrew Vasquez } else {
34255f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
34265f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
34271c7c6357SAndrew Vasquez }
34281c7c6357SAndrew Vasquez
34297b867cf7SAnirban Chakraborty dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
34301c7c6357SAndrew Vasquez
34311c7c6357SAndrew Vasquez return rval;
34321c7c6357SAndrew Vasquez }
34331c7c6357SAndrew Vasquez
3434523ec773SAndrew Vasquez int
qla24xx_abort_target(struct fc_port * fcport,uint64_t l,int tag)34359cb78c16SHannes Reinecke qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
3436523ec773SAndrew Vasquez {
34373822263eSMadhuranath Iyengar struct qla_hw_data *ha = fcport->vha->hw;
34383822263eSMadhuranath Iyengar
34393822263eSMadhuranath Iyengar if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
34403822263eSMadhuranath Iyengar return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
34413822263eSMadhuranath Iyengar
34422afa19a9SAnirban Chakraborty return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
3443523ec773SAndrew Vasquez }
3444523ec773SAndrew Vasquez
3445523ec773SAndrew Vasquez int
qla24xx_lun_reset(struct fc_port * fcport,uint64_t l,int tag)34469cb78c16SHannes Reinecke qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
3447523ec773SAndrew Vasquez {
34483822263eSMadhuranath Iyengar struct qla_hw_data *ha = fcport->vha->hw;
34493822263eSMadhuranath Iyengar
34503822263eSMadhuranath Iyengar if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
34513822263eSMadhuranath Iyengar return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
34523822263eSMadhuranath Iyengar
34532afa19a9SAnirban Chakraborty return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
3454523ec773SAndrew Vasquez }
3455523ec773SAndrew Vasquez
34561c7c6357SAndrew Vasquez int
qla2x00_system_error(scsi_qla_host_t * vha)34577b867cf7SAnirban Chakraborty qla2x00_system_error(scsi_qla_host_t *vha)
34581c7c6357SAndrew Vasquez {
34591c7c6357SAndrew Vasquez int rval;
34601c7c6357SAndrew Vasquez mbx_cmd_t mc;
34611c7c6357SAndrew Vasquez mbx_cmd_t *mcp = &mc;
34627b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
34631c7c6357SAndrew Vasquez
346468af0811SAndrew Vasquez if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
34651c7c6357SAndrew Vasquez return QLA_FUNCTION_FAILED;
34661c7c6357SAndrew Vasquez
34675f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
34685f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
34691c7c6357SAndrew Vasquez
34701c7c6357SAndrew Vasquez mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
34711c7c6357SAndrew Vasquez mcp->out_mb = MBX_0;
34721c7c6357SAndrew Vasquez mcp->in_mb = MBX_0;
34731c7c6357SAndrew Vasquez mcp->tov = 5;
34741c7c6357SAndrew Vasquez mcp->flags = 0;
34757b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
34761c7c6357SAndrew Vasquez
34771c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
34787c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
34791c7c6357SAndrew Vasquez } else {
34805f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
34815f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
34821c7c6357SAndrew Vasquez }
34831c7c6357SAndrew Vasquez
34841c7c6357SAndrew Vasquez return rval;
34851c7c6357SAndrew Vasquez }
34861c7c6357SAndrew Vasquez
3487db64e930SJoe Carnuccio int
qla2x00_write_serdes_word(scsi_qla_host_t * vha,uint16_t addr,uint16_t data)3488db64e930SJoe Carnuccio qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
3489db64e930SJoe Carnuccio {
3490db64e930SJoe Carnuccio int rval;
3491db64e930SJoe Carnuccio mbx_cmd_t mc;
3492db64e930SJoe Carnuccio mbx_cmd_t *mcp = &mc;
3493db64e930SJoe Carnuccio
3494f299c7c2SJoe Carnuccio if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3495ecc89f25SJoe Carnuccio !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))
3496db64e930SJoe Carnuccio return QLA_FUNCTION_FAILED;
3497db64e930SJoe Carnuccio
3498db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
3499db64e930SJoe Carnuccio "Entered %s.\n", __func__);
3500db64e930SJoe Carnuccio
3501db64e930SJoe Carnuccio mcp->mb[0] = MBC_WRITE_SERDES;
3502db64e930SJoe Carnuccio mcp->mb[1] = addr;
3503064135e0SAndrew Vasquez if (IS_QLA2031(vha->hw))
3504db64e930SJoe Carnuccio mcp->mb[2] = data & 0xff;
3505064135e0SAndrew Vasquez else
3506064135e0SAndrew Vasquez mcp->mb[2] = data;
3507064135e0SAndrew Vasquez
3508db64e930SJoe Carnuccio mcp->mb[3] = 0;
3509db64e930SJoe Carnuccio mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3510db64e930SJoe Carnuccio mcp->in_mb = MBX_0;
3511db64e930SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
3512db64e930SJoe Carnuccio mcp->flags = 0;
3513db64e930SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
3514db64e930SJoe Carnuccio
3515db64e930SJoe Carnuccio if (rval != QLA_SUCCESS) {
3516db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1183,
3517db64e930SJoe Carnuccio "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3518db64e930SJoe Carnuccio } else {
3519db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3520db64e930SJoe Carnuccio "Done %s.\n", __func__);
3521db64e930SJoe Carnuccio }
3522db64e930SJoe Carnuccio
3523db64e930SJoe Carnuccio return rval;
3524db64e930SJoe Carnuccio }
3525db64e930SJoe Carnuccio
3526db64e930SJoe Carnuccio int
qla2x00_read_serdes_word(scsi_qla_host_t * vha,uint16_t addr,uint16_t * data)3527db64e930SJoe Carnuccio qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3528db64e930SJoe Carnuccio {
3529db64e930SJoe Carnuccio int rval;
3530db64e930SJoe Carnuccio mbx_cmd_t mc;
3531db64e930SJoe Carnuccio mbx_cmd_t *mcp = &mc;
3532db64e930SJoe Carnuccio
3533f299c7c2SJoe Carnuccio if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3534ecc89f25SJoe Carnuccio !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))
3535db64e930SJoe Carnuccio return QLA_FUNCTION_FAILED;
3536db64e930SJoe Carnuccio
3537db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3538db64e930SJoe Carnuccio "Entered %s.\n", __func__);
3539db64e930SJoe Carnuccio
3540db64e930SJoe Carnuccio mcp->mb[0] = MBC_READ_SERDES;
3541db64e930SJoe Carnuccio mcp->mb[1] = addr;
3542db64e930SJoe Carnuccio mcp->mb[3] = 0;
3543db64e930SJoe Carnuccio mcp->out_mb = MBX_3|MBX_1|MBX_0;
3544db64e930SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
3545db64e930SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
3546db64e930SJoe Carnuccio mcp->flags = 0;
3547db64e930SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
3548db64e930SJoe Carnuccio
3549064135e0SAndrew Vasquez if (IS_QLA2031(vha->hw))
3550db64e930SJoe Carnuccio *data = mcp->mb[1] & 0xff;
3551064135e0SAndrew Vasquez else
3552064135e0SAndrew Vasquez *data = mcp->mb[1];
3553db64e930SJoe Carnuccio
3554db64e930SJoe Carnuccio if (rval != QLA_SUCCESS) {
3555db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1186,
3556db64e930SJoe Carnuccio "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3557db64e930SJoe Carnuccio } else {
3558db64e930SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3559db64e930SJoe Carnuccio "Done %s.\n", __func__);
3560db64e930SJoe Carnuccio }
3561db64e930SJoe Carnuccio
3562db64e930SJoe Carnuccio return rval;
3563db64e930SJoe Carnuccio }
3564db64e930SJoe Carnuccio
3565e8887c51SJoe Carnuccio int
qla8044_write_serdes_word(scsi_qla_host_t * vha,uint32_t addr,uint32_t data)3566e8887c51SJoe Carnuccio qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3567e8887c51SJoe Carnuccio {
3568e8887c51SJoe Carnuccio int rval;
3569e8887c51SJoe Carnuccio mbx_cmd_t mc;
3570e8887c51SJoe Carnuccio mbx_cmd_t *mcp = &mc;
3571e8887c51SJoe Carnuccio
3572e8887c51SJoe Carnuccio if (!IS_QLA8044(vha->hw))
3573e8887c51SJoe Carnuccio return QLA_FUNCTION_FAILED;
3574e8887c51SJoe Carnuccio
357583548fe2SQuinn Tran ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0,
3576e8887c51SJoe Carnuccio "Entered %s.\n", __func__);
3577e8887c51SJoe Carnuccio
3578e8887c51SJoe Carnuccio mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3579e8887c51SJoe Carnuccio mcp->mb[1] = HCS_WRITE_SERDES;
3580e8887c51SJoe Carnuccio mcp->mb[3] = LSW(addr);
3581e8887c51SJoe Carnuccio mcp->mb[4] = MSW(addr);
3582e8887c51SJoe Carnuccio mcp->mb[5] = LSW(data);
3583e8887c51SJoe Carnuccio mcp->mb[6] = MSW(data);
3584e8887c51SJoe Carnuccio mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3585e8887c51SJoe Carnuccio mcp->in_mb = MBX_0;
3586e8887c51SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
3587e8887c51SJoe Carnuccio mcp->flags = 0;
3588e8887c51SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
3589e8887c51SJoe Carnuccio
3590e8887c51SJoe Carnuccio if (rval != QLA_SUCCESS) {
359183548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x11a1,
3592e8887c51SJoe Carnuccio "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3593e8887c51SJoe Carnuccio } else {
3594e8887c51SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3595e8887c51SJoe Carnuccio "Done %s.\n", __func__);
3596e8887c51SJoe Carnuccio }
3597e8887c51SJoe Carnuccio
3598e8887c51SJoe Carnuccio return rval;
3599e8887c51SJoe Carnuccio }
3600e8887c51SJoe Carnuccio
3601e8887c51SJoe Carnuccio int
qla8044_read_serdes_word(scsi_qla_host_t * vha,uint32_t addr,uint32_t * data)3602e8887c51SJoe Carnuccio qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3603e8887c51SJoe Carnuccio {
3604e8887c51SJoe Carnuccio int rval;
3605e8887c51SJoe Carnuccio mbx_cmd_t mc;
3606e8887c51SJoe Carnuccio mbx_cmd_t *mcp = &mc;
3607e8887c51SJoe Carnuccio
3608e8887c51SJoe Carnuccio if (!IS_QLA8044(vha->hw))
3609e8887c51SJoe Carnuccio return QLA_FUNCTION_FAILED;
3610e8887c51SJoe Carnuccio
3611e8887c51SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3612e8887c51SJoe Carnuccio "Entered %s.\n", __func__);
3613e8887c51SJoe Carnuccio
3614e8887c51SJoe Carnuccio mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3615e8887c51SJoe Carnuccio mcp->mb[1] = HCS_READ_SERDES;
3616e8887c51SJoe Carnuccio mcp->mb[3] = LSW(addr);
3617e8887c51SJoe Carnuccio mcp->mb[4] = MSW(addr);
3618e8887c51SJoe Carnuccio mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3619e8887c51SJoe Carnuccio mcp->in_mb = MBX_2|MBX_1|MBX_0;
3620e8887c51SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
3621e8887c51SJoe Carnuccio mcp->flags = 0;
3622e8887c51SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
3623e8887c51SJoe Carnuccio
3624e8887c51SJoe Carnuccio *data = mcp->mb[2] << 16 | mcp->mb[1];
3625e8887c51SJoe Carnuccio
3626e8887c51SJoe Carnuccio if (rval != QLA_SUCCESS) {
3627e8887c51SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x118a,
3628e8887c51SJoe Carnuccio "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3629e8887c51SJoe Carnuccio } else {
3630e8887c51SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3631e8887c51SJoe Carnuccio "Done %s.\n", __func__);
3632e8887c51SJoe Carnuccio }
3633e8887c51SJoe Carnuccio
3634e8887c51SJoe Carnuccio return rval;
3635e8887c51SJoe Carnuccio }
3636e8887c51SJoe Carnuccio
36371c7c6357SAndrew Vasquez /**
36381c7c6357SAndrew Vasquez * qla2x00_set_serdes_params() -
36392db6228dSBart Van Assche * @vha: HA context
3640807eb907SBart Van Assche * @sw_em_1g: serial link options
3641807eb907SBart Van Assche * @sw_em_2g: serial link options
3642807eb907SBart Van Assche * @sw_em_4g: serial link options
36431c7c6357SAndrew Vasquez *
36441c7c6357SAndrew Vasquez * Returns
36451c7c6357SAndrew Vasquez */
36461c7c6357SAndrew Vasquez int
qla2x00_set_serdes_params(scsi_qla_host_t * vha,uint16_t sw_em_1g,uint16_t sw_em_2g,uint16_t sw_em_4g)36477b867cf7SAnirban Chakraborty qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
36481c7c6357SAndrew Vasquez uint16_t sw_em_2g, uint16_t sw_em_4g)
36491c7c6357SAndrew Vasquez {
36501c7c6357SAndrew Vasquez int rval;
36511c7c6357SAndrew Vasquez mbx_cmd_t mc;
36521c7c6357SAndrew Vasquez mbx_cmd_t *mcp = &mc;
36531c7c6357SAndrew Vasquez
36545f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
36555f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
36561c7c6357SAndrew Vasquez
36571c7c6357SAndrew Vasquez mcp->mb[0] = MBC_SERDES_PARAMS;
36581c7c6357SAndrew Vasquez mcp->mb[1] = BIT_0;
3659fdbc6833Sandrew.vasquez@qlogic.com mcp->mb[2] = sw_em_1g | BIT_15;
3660fdbc6833Sandrew.vasquez@qlogic.com mcp->mb[3] = sw_em_2g | BIT_15;
3661fdbc6833Sandrew.vasquez@qlogic.com mcp->mb[4] = sw_em_4g | BIT_15;
36621c7c6357SAndrew Vasquez mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
36631c7c6357SAndrew Vasquez mcp->in_mb = MBX_0;
3664b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
36651c7c6357SAndrew Vasquez mcp->flags = 0;
36667b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
36671c7c6357SAndrew Vasquez
36681c7c6357SAndrew Vasquez if (rval != QLA_SUCCESS) {
36691c7c6357SAndrew Vasquez /*EMPTY*/
36707c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x109f,
36717c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
36721c7c6357SAndrew Vasquez } else {
36731c7c6357SAndrew Vasquez /*EMPTY*/
36745f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
36755f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
36761c7c6357SAndrew Vasquez }
36771c7c6357SAndrew Vasquez
36781c7c6357SAndrew Vasquez return rval;
36791c7c6357SAndrew Vasquez }
3680f6ef3b18SAndrew Vasquez
3681f6ef3b18SAndrew Vasquez int
qla2x00_stop_firmware(scsi_qla_host_t * vha)36827b867cf7SAnirban Chakraborty qla2x00_stop_firmware(scsi_qla_host_t *vha)
3683f6ef3b18SAndrew Vasquez {
3684f6ef3b18SAndrew Vasquez int rval;
3685f6ef3b18SAndrew Vasquez mbx_cmd_t mc;
3686f6ef3b18SAndrew Vasquez mbx_cmd_t *mcp = &mc;
3687f6ef3b18SAndrew Vasquez
36887b867cf7SAnirban Chakraborty if (!IS_FWI2_CAPABLE(vha->hw))
3689f6ef3b18SAndrew Vasquez return QLA_FUNCTION_FAILED;
3690f6ef3b18SAndrew Vasquez
36915f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
36925f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
3693f6ef3b18SAndrew Vasquez
3694f6ef3b18SAndrew Vasquez mcp->mb[0] = MBC_STOP_FIRMWARE;
36954ba988dbSAndrew Vasquez mcp->mb[1] = 0;
36964ba988dbSAndrew Vasquez mcp->out_mb = MBX_1|MBX_0;
3697f6ef3b18SAndrew Vasquez mcp->in_mb = MBX_0;
3698f6ef3b18SAndrew Vasquez mcp->tov = 5;
3699f6ef3b18SAndrew Vasquez mcp->flags = 0;
37007b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3701f6ef3b18SAndrew Vasquez
3702f6ef3b18SAndrew Vasquez if (rval != QLA_SUCCESS) {
37037c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
3704b469a7cbSAndrew Vasquez if (mcp->mb[0] == MBS_INVALID_COMMAND)
3705b469a7cbSAndrew Vasquez rval = QLA_INVALID_COMMAND;
3706f6ef3b18SAndrew Vasquez } else {
37075f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
37085f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3709f6ef3b18SAndrew Vasquez }
3710f6ef3b18SAndrew Vasquez
3711f6ef3b18SAndrew Vasquez return rval;
3712f6ef3b18SAndrew Vasquez }
3713a7a167bfSAndrew Vasquez
3714a7a167bfSAndrew Vasquez int
qla2x00_enable_eft_trace(scsi_qla_host_t * vha,dma_addr_t eft_dma,uint16_t buffers)37157b867cf7SAnirban Chakraborty qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
3716a7a167bfSAndrew Vasquez uint16_t buffers)
3717a7a167bfSAndrew Vasquez {
3718a7a167bfSAndrew Vasquez int rval;
3719a7a167bfSAndrew Vasquez mbx_cmd_t mc;
3720a7a167bfSAndrew Vasquez mbx_cmd_t *mcp = &mc;
3721a7a167bfSAndrew Vasquez
37225f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
37235f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
37247c3df132SSaurav Kashyap
37257b867cf7SAnirban Chakraborty if (!IS_FWI2_CAPABLE(vha->hw))
3726a7a167bfSAndrew Vasquez return QLA_FUNCTION_FAILED;
3727a7a167bfSAndrew Vasquez
372885880801SAndrew Vasquez if (unlikely(pci_channel_offline(vha->hw->pdev)))
372985880801SAndrew Vasquez return QLA_FUNCTION_FAILED;
373085880801SAndrew Vasquez
3731a7a167bfSAndrew Vasquez mcp->mb[0] = MBC_TRACE_CONTROL;
373200b6bd25SAndrew Vasquez mcp->mb[1] = TC_EFT_ENABLE;
3733a7a167bfSAndrew Vasquez mcp->mb[2] = LSW(eft_dma);
3734a7a167bfSAndrew Vasquez mcp->mb[3] = MSW(eft_dma);
3735a7a167bfSAndrew Vasquez mcp->mb[4] = LSW(MSD(eft_dma));
3736a7a167bfSAndrew Vasquez mcp->mb[5] = MSW(MSD(eft_dma));
3737a7a167bfSAndrew Vasquez mcp->mb[6] = buffers;
373800b6bd25SAndrew Vasquez mcp->mb[7] = TC_AEN_DISABLE;
373900b6bd25SAndrew Vasquez mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
374000b6bd25SAndrew Vasquez mcp->in_mb = MBX_1|MBX_0;
3741b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
3742a7a167bfSAndrew Vasquez mcp->flags = 0;
37437b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
374400b6bd25SAndrew Vasquez if (rval != QLA_SUCCESS) {
37457c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10a5,
37467c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
37477c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
374800b6bd25SAndrew Vasquez } else {
37495f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
37505f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
375100b6bd25SAndrew Vasquez }
3752a7a167bfSAndrew Vasquez
375300b6bd25SAndrew Vasquez return rval;
375400b6bd25SAndrew Vasquez }
375500b6bd25SAndrew Vasquez
375600b6bd25SAndrew Vasquez int
qla2x00_disable_eft_trace(scsi_qla_host_t * vha)37577b867cf7SAnirban Chakraborty qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
375800b6bd25SAndrew Vasquez {
375900b6bd25SAndrew Vasquez int rval;
376000b6bd25SAndrew Vasquez mbx_cmd_t mc;
376100b6bd25SAndrew Vasquez mbx_cmd_t *mcp = &mc;
376200b6bd25SAndrew Vasquez
37635f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
37645f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
37657c3df132SSaurav Kashyap
37667b867cf7SAnirban Chakraborty if (!IS_FWI2_CAPABLE(vha->hw))
376700b6bd25SAndrew Vasquez return QLA_FUNCTION_FAILED;
376800b6bd25SAndrew Vasquez
376985880801SAndrew Vasquez if (unlikely(pci_channel_offline(vha->hw->pdev)))
377085880801SAndrew Vasquez return QLA_FUNCTION_FAILED;
377185880801SAndrew Vasquez
377200b6bd25SAndrew Vasquez mcp->mb[0] = MBC_TRACE_CONTROL;
377300b6bd25SAndrew Vasquez mcp->mb[1] = TC_EFT_DISABLE;
377400b6bd25SAndrew Vasquez mcp->out_mb = MBX_1|MBX_0;
377500b6bd25SAndrew Vasquez mcp->in_mb = MBX_1|MBX_0;
3776b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
377700b6bd25SAndrew Vasquez mcp->flags = 0;
37787b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3779a7a167bfSAndrew Vasquez if (rval != QLA_SUCCESS) {
37807c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10a8,
37817c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
37827c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
3783a7a167bfSAndrew Vasquez } else {
37845f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
37855f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3786a7a167bfSAndrew Vasquez }
3787a7a167bfSAndrew Vasquez
3788a7a167bfSAndrew Vasquez return rval;
3789a7a167bfSAndrew Vasquez }
3790a7a167bfSAndrew Vasquez
379188729e53SAndrew Vasquez int
qla2x00_enable_fce_trace(scsi_qla_host_t * vha,dma_addr_t fce_dma,uint16_t buffers,uint16_t * mb,uint32_t * dwords)37927b867cf7SAnirban Chakraborty qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
3793df613b96SAndrew Vasquez uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3794df613b96SAndrew Vasquez {
3795df613b96SAndrew Vasquez int rval;
3796df613b96SAndrew Vasquez mbx_cmd_t mc;
3797df613b96SAndrew Vasquez mbx_cmd_t *mcp = &mc;
3798df613b96SAndrew Vasquez
37995f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
38005f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
38017c3df132SSaurav Kashyap
38026246b8a1SGiridhar Malavali if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
3803ecc89f25SJoe Carnuccio !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
3804ecc89f25SJoe Carnuccio !IS_QLA28XX(vha->hw))
3805df613b96SAndrew Vasquez return QLA_FUNCTION_FAILED;
3806df613b96SAndrew Vasquez
380785880801SAndrew Vasquez if (unlikely(pci_channel_offline(vha->hw->pdev)))
380885880801SAndrew Vasquez return QLA_FUNCTION_FAILED;
380985880801SAndrew Vasquez
3810df613b96SAndrew Vasquez mcp->mb[0] = MBC_TRACE_CONTROL;
3811df613b96SAndrew Vasquez mcp->mb[1] = TC_FCE_ENABLE;
3812df613b96SAndrew Vasquez mcp->mb[2] = LSW(fce_dma);
3813df613b96SAndrew Vasquez mcp->mb[3] = MSW(fce_dma);
3814df613b96SAndrew Vasquez mcp->mb[4] = LSW(MSD(fce_dma));
3815df613b96SAndrew Vasquez mcp->mb[5] = MSW(MSD(fce_dma));
3816df613b96SAndrew Vasquez mcp->mb[6] = buffers;
3817df613b96SAndrew Vasquez mcp->mb[7] = TC_AEN_DISABLE;
3818df613b96SAndrew Vasquez mcp->mb[8] = 0;
3819df613b96SAndrew Vasquez mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3820df613b96SAndrew Vasquez mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3821df613b96SAndrew Vasquez mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3822df613b96SAndrew Vasquez MBX_1|MBX_0;
3823df613b96SAndrew Vasquez mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3824b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
3825df613b96SAndrew Vasquez mcp->flags = 0;
38267b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3827df613b96SAndrew Vasquez if (rval != QLA_SUCCESS) {
38287c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10ab,
38297c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
38307c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
3831df613b96SAndrew Vasquez } else {
38325f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
38335f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3834df613b96SAndrew Vasquez
3835df613b96SAndrew Vasquez if (mb)
3836df613b96SAndrew Vasquez memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3837df613b96SAndrew Vasquez if (dwords)
3838fa0926dfSAndrew Vasquez *dwords = buffers;
3839df613b96SAndrew Vasquez }
3840df613b96SAndrew Vasquez
3841df613b96SAndrew Vasquez return rval;
3842df613b96SAndrew Vasquez }
3843df613b96SAndrew Vasquez
3844df613b96SAndrew Vasquez int
qla2x00_disable_fce_trace(scsi_qla_host_t * vha,uint64_t * wr,uint64_t * rd)38457b867cf7SAnirban Chakraborty qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
3846df613b96SAndrew Vasquez {
3847df613b96SAndrew Vasquez int rval;
3848df613b96SAndrew Vasquez mbx_cmd_t mc;
3849df613b96SAndrew Vasquez mbx_cmd_t *mcp = &mc;
3850df613b96SAndrew Vasquez
38515f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
38525f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
38537c3df132SSaurav Kashyap
38547b867cf7SAnirban Chakraborty if (!IS_FWI2_CAPABLE(vha->hw))
3855df613b96SAndrew Vasquez return QLA_FUNCTION_FAILED;
3856df613b96SAndrew Vasquez
385785880801SAndrew Vasquez if (unlikely(pci_channel_offline(vha->hw->pdev)))
385885880801SAndrew Vasquez return QLA_FUNCTION_FAILED;
385985880801SAndrew Vasquez
3860df613b96SAndrew Vasquez mcp->mb[0] = MBC_TRACE_CONTROL;
3861df613b96SAndrew Vasquez mcp->mb[1] = TC_FCE_DISABLE;
3862df613b96SAndrew Vasquez mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3863df613b96SAndrew Vasquez mcp->out_mb = MBX_2|MBX_1|MBX_0;
3864df613b96SAndrew Vasquez mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3865df613b96SAndrew Vasquez MBX_1|MBX_0;
3866b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
3867df613b96SAndrew Vasquez mcp->flags = 0;
38687b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3869df613b96SAndrew Vasquez if (rval != QLA_SUCCESS) {
38707c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10ae,
38717c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
38727c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
3873df613b96SAndrew Vasquez } else {
38745f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
38755f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3876df613b96SAndrew Vasquez
3877df613b96SAndrew Vasquez if (wr)
3878df613b96SAndrew Vasquez *wr = (uint64_t) mcp->mb[5] << 48 |
3879df613b96SAndrew Vasquez (uint64_t) mcp->mb[4] << 32 |
3880df613b96SAndrew Vasquez (uint64_t) mcp->mb[3] << 16 |
3881df613b96SAndrew Vasquez (uint64_t) mcp->mb[2];
3882df613b96SAndrew Vasquez if (rd)
3883df613b96SAndrew Vasquez *rd = (uint64_t) mcp->mb[9] << 48 |
3884df613b96SAndrew Vasquez (uint64_t) mcp->mb[8] << 32 |
3885df613b96SAndrew Vasquez (uint64_t) mcp->mb[7] << 16 |
3886df613b96SAndrew Vasquez (uint64_t) mcp->mb[6];
3887df613b96SAndrew Vasquez }
3888df613b96SAndrew Vasquez
3889df613b96SAndrew Vasquez return rval;
3890df613b96SAndrew Vasquez }
3891df613b96SAndrew Vasquez
3892df613b96SAndrew Vasquez int
qla2x00_get_idma_speed(scsi_qla_host_t * vha,uint16_t loop_id,uint16_t * port_speed,uint16_t * mb)38936e98016cSGiridhar Malavali qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
38946e98016cSGiridhar Malavali uint16_t *port_speed, uint16_t *mb)
38956e98016cSGiridhar Malavali {
38966e98016cSGiridhar Malavali int rval;
38976e98016cSGiridhar Malavali mbx_cmd_t mc;
38986e98016cSGiridhar Malavali mbx_cmd_t *mcp = &mc;
38996e98016cSGiridhar Malavali
39005f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
39015f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
39027c3df132SSaurav Kashyap
39036e98016cSGiridhar Malavali if (!IS_IIDMA_CAPABLE(vha->hw))
39046e98016cSGiridhar Malavali return QLA_FUNCTION_FAILED;
39056e98016cSGiridhar Malavali
39066e98016cSGiridhar Malavali mcp->mb[0] = MBC_PORT_PARAMS;
39076e98016cSGiridhar Malavali mcp->mb[1] = loop_id;
39086e98016cSGiridhar Malavali mcp->mb[2] = mcp->mb[3] = 0;
39096e98016cSGiridhar Malavali mcp->mb[9] = vha->vp_idx;
39106e98016cSGiridhar Malavali mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
39116e98016cSGiridhar Malavali mcp->in_mb = MBX_3|MBX_1|MBX_0;
39126e98016cSGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
39136e98016cSGiridhar Malavali mcp->flags = 0;
39146e98016cSGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
39156e98016cSGiridhar Malavali
39166e98016cSGiridhar Malavali /* Return mailbox statuses. */
39172a3192a3SJoe Carnuccio if (mb) {
39186e98016cSGiridhar Malavali mb[0] = mcp->mb[0];
39196e98016cSGiridhar Malavali mb[1] = mcp->mb[1];
39206e98016cSGiridhar Malavali mb[3] = mcp->mb[3];
39216e98016cSGiridhar Malavali }
39226e98016cSGiridhar Malavali
39236e98016cSGiridhar Malavali if (rval != QLA_SUCCESS) {
39247c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
39256e98016cSGiridhar Malavali } else {
39265f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
39275f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
39286e98016cSGiridhar Malavali if (port_speed)
39296e98016cSGiridhar Malavali *port_speed = mcp->mb[3];
39306e98016cSGiridhar Malavali }
39316e98016cSGiridhar Malavali
39326e98016cSGiridhar Malavali return rval;
39336e98016cSGiridhar Malavali }
39346e98016cSGiridhar Malavali
39356e98016cSGiridhar Malavali int
qla2x00_set_idma_speed(scsi_qla_host_t * vha,uint16_t loop_id,uint16_t port_speed,uint16_t * mb)39367b867cf7SAnirban Chakraborty qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3937d8b45213SAndrew Vasquez uint16_t port_speed, uint16_t *mb)
3938d8b45213SAndrew Vasquez {
3939d8b45213SAndrew Vasquez int rval;
3940d8b45213SAndrew Vasquez mbx_cmd_t mc;
3941d8b45213SAndrew Vasquez mbx_cmd_t *mcp = &mc;
3942d8b45213SAndrew Vasquez
39435f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
39445f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
39457c3df132SSaurav Kashyap
39467b867cf7SAnirban Chakraborty if (!IS_IIDMA_CAPABLE(vha->hw))
3947d8b45213SAndrew Vasquez return QLA_FUNCTION_FAILED;
3948d8b45213SAndrew Vasquez
3949d8b45213SAndrew Vasquez mcp->mb[0] = MBC_PORT_PARAMS;
3950d8b45213SAndrew Vasquez mcp->mb[1] = loop_id;
3951d8b45213SAndrew Vasquez mcp->mb[2] = BIT_0;
39522a3192a3SJoe Carnuccio mcp->mb[3] = port_speed & 0x3F;
39531bb39548SHarish Zunjarrao mcp->mb[9] = vha->vp_idx;
39541bb39548SHarish Zunjarrao mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
39551bb39548SHarish Zunjarrao mcp->in_mb = MBX_3|MBX_1|MBX_0;
3956b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
3957d8b45213SAndrew Vasquez mcp->flags = 0;
39587b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
3959d8b45213SAndrew Vasquez
3960d8b45213SAndrew Vasquez /* Return mailbox statuses. */
39612a3192a3SJoe Carnuccio if (mb) {
3962d8b45213SAndrew Vasquez mb[0] = mcp->mb[0];
3963d8b45213SAndrew Vasquez mb[1] = mcp->mb[1];
3964d8b45213SAndrew Vasquez mb[3] = mcp->mb[3];
3965d8b45213SAndrew Vasquez }
3966d8b45213SAndrew Vasquez
3967d8b45213SAndrew Vasquez if (rval != QLA_SUCCESS) {
39685f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10b4,
39695f28d2d7SSaurav Kashyap "Failed=%x.\n", rval);
3970d8b45213SAndrew Vasquez } else {
39715f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
39725f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
3973d8b45213SAndrew Vasquez }
3974d8b45213SAndrew Vasquez
3975d8b45213SAndrew Vasquez return rval;
3976d8b45213SAndrew Vasquez }
39772c3dfe3fSSeokmann Ju
39782c3dfe3fSSeokmann Ju void
qla24xx_report_id_acquisition(scsi_qla_host_t * vha,struct vp_rpt_id_entry_24xx * rptid_entry)39797b867cf7SAnirban Chakraborty qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
39802c3dfe3fSSeokmann Ju struct vp_rpt_id_entry_24xx *rptid_entry)
39812c3dfe3fSSeokmann Ju {
39827b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
398341dc529aSQuinn Tran scsi_qla_host_t *vp = NULL;
3984feafb7b1SArun Easi unsigned long flags;
39854ac8d4caSAndrew Vasquez int found;
3986482c9dc7SQuinn Tran port_id_t id;
39879cd883f0SQuinn Tran struct fc_port *fcport;
39882c3dfe3fSSeokmann Ju
39895f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
39905f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
39917c3df132SSaurav Kashyap
39922c3dfe3fSSeokmann Ju if (rptid_entry->entry_status != 0)
39932c3dfe3fSSeokmann Ju return;
39942c3dfe3fSSeokmann Ju
3995482c9dc7SQuinn Tran id.b.domain = rptid_entry->port_id[2];
3996482c9dc7SQuinn Tran id.b.area = rptid_entry->port_id[1];
3997482c9dc7SQuinn Tran id.b.al_pa = rptid_entry->port_id[0];
3998482c9dc7SQuinn Tran id.b.rsvd_1 = 0;
39991763c1fdSDarren Trapp ha->flags.n2n_ae = 0;
4000482c9dc7SQuinn Tran
40012c3dfe3fSSeokmann Ju if (rptid_entry->format == 0) {
400241dc529aSQuinn Tran /* loop */
4003ec7193e2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x10b7,
40047c3df132SSaurav Kashyap "Format 0 : Number of VPs setup %d, number of "
400541dc529aSQuinn Tran "VPs acquired %d.\n", rptid_entry->vp_setup,
400641dc529aSQuinn Tran rptid_entry->vp_acquired);
4007ec7193e2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x10b8,
40087c3df132SSaurav Kashyap "Primary port id %02x%02x%02x.\n",
40092c3dfe3fSSeokmann Ju rptid_entry->port_id[2], rptid_entry->port_id[1],
40107c3df132SSaurav Kashyap rptid_entry->port_id[0]);
40119cd883f0SQuinn Tran ha->current_topology = ISP_CFG_NL;
4012430eef03SQuinn Tran qla_update_host_map(vha, id);
401341dc529aSQuinn Tran
40142c3dfe3fSSeokmann Ju } else if (rptid_entry->format == 1) {
401541dc529aSQuinn Tran /* fabric */
4016ec7193e2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x10b9,
40177c3df132SSaurav Kashyap "Format 1: VP[%d] enabled - status %d - with "
401841dc529aSQuinn Tran "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
401941dc529aSQuinn Tran rptid_entry->vp_status,
40202c3dfe3fSSeokmann Ju rptid_entry->port_id[2], rptid_entry->port_id[1],
40217c3df132SSaurav Kashyap rptid_entry->port_id[0]);
4022edd05de1SDuane Grigsby ql_dbg(ql_dbg_async, vha, 0x5075,
4023edd05de1SDuane Grigsby "Format 1: Remote WWPN %8phC.\n",
4024edd05de1SDuane Grigsby rptid_entry->u.f1.port_name);
4025edd05de1SDuane Grigsby
4026edd05de1SDuane Grigsby ql_dbg(ql_dbg_async, vha, 0x5075,
4027edd05de1SDuane Grigsby "Format 1: WWPN %8phC.\n",
4028edd05de1SDuane Grigsby vha->port_name);
4029edd05de1SDuane Grigsby
40308777e431SQuinn Tran switch (rptid_entry->u.f1.flags & TOPO_MASK) {
40318777e431SQuinn Tran case TOPO_N2N:
40328777e431SQuinn Tran ha->current_topology = ISP_CFG_N;
40338777e431SQuinn Tran spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
40347f2a398dSQuinn Tran list_for_each_entry(fcport, &vha->vp_fcports, list) {
40357f2a398dSQuinn Tran fcport->scan_state = QLA_FCPORT_SCAN;
40367f2a398dSQuinn Tran fcport->n2n_flag = 0;
40377f2a398dSQuinn Tran }
4038ad8a260aSQuinn Tran id.b24 = 0;
4039ad8a260aSQuinn Tran if (wwn_to_u64(vha->port_name) >
4040ad8a260aSQuinn Tran wwn_to_u64(rptid_entry->u.f1.port_name)) {
4041ad8a260aSQuinn Tran vha->d_id.b24 = 0;
4042ad8a260aSQuinn Tran vha->d_id.b.al_pa = 1;
4043ad8a260aSQuinn Tran ha->flags.n2n_bigger = 1;
4044ad8a260aSQuinn Tran
4045ad8a260aSQuinn Tran id.b.al_pa = 2;
4046ad8a260aSQuinn Tran ql_dbg(ql_dbg_async, vha, 0x5075,
4047ad8a260aSQuinn Tran "Format 1: assign local id %x remote id %x\n",
4048ad8a260aSQuinn Tran vha->d_id.b24, id.b24);
4049ad8a260aSQuinn Tran } else {
4050ad8a260aSQuinn Tran ql_dbg(ql_dbg_async, vha, 0x5075,
4051ad8a260aSQuinn Tran "Format 1: Remote login - Waiting for WWPN %8phC.\n",
4052ad8a260aSQuinn Tran rptid_entry->u.f1.port_name);
4053ad8a260aSQuinn Tran ha->flags.n2n_bigger = 0;
4054ad8a260aSQuinn Tran }
40557f2a398dSQuinn Tran
40568777e431SQuinn Tran fcport = qla2x00_find_fcport_by_wwpn(vha,
40578777e431SQuinn Tran rptid_entry->u.f1.port_name, 1);
40588777e431SQuinn Tran spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
40598777e431SQuinn Tran
4060ad8a260aSQuinn Tran
40618777e431SQuinn Tran if (fcport) {
40628777e431SQuinn Tran fcport->plogi_nack_done_deadline = jiffies + HZ;
406394eda271SArun Easi fcport->dm_login_expire = jiffies +
406494eda271SArun Easi QLA_N2N_WAIT_TIME * HZ;
40658777e431SQuinn Tran fcport->scan_state = QLA_FCPORT_FOUND;
40667f2a398dSQuinn Tran fcport->n2n_flag = 1;
4067f3f1938bSQuinn Tran fcport->keep_nport_handle = 1;
40684de067e5SQuinn Tran fcport->login_retry = vha->hw->login_retry_count;
4069f8844457SQuinn Tran fcport->fc4_type = FS_FC4TYPE_FCP;
4070f8844457SQuinn Tran if (vha->flags.nvme_enabled)
4071f8844457SQuinn Tran fcport->fc4_type |= FS_FC4TYPE_NVME;
40727f2a398dSQuinn Tran
4073ad8a260aSQuinn Tran if (wwn_to_u64(vha->port_name) >
4074ad8a260aSQuinn Tran wwn_to_u64(fcport->port_name)) {
4075ad8a260aSQuinn Tran fcport->d_id = id;
4076ad8a260aSQuinn Tran }
4077ad8a260aSQuinn Tran
40788777e431SQuinn Tran switch (fcport->disc_state) {
40798777e431SQuinn Tran case DSC_DELETED:
40808777e431SQuinn Tran set_bit(RELOGIN_NEEDED,
40818777e431SQuinn Tran &vha->dpc_flags);
40828777e431SQuinn Tran break;
40838777e431SQuinn Tran case DSC_DELETE_PEND:
40848777e431SQuinn Tran break;
40858777e431SQuinn Tran default:
40868777e431SQuinn Tran qlt_schedule_sess_for_deletion(fcport);
40878777e431SQuinn Tran break;
40888777e431SQuinn Tran }
40898777e431SQuinn Tran } else {
40908777e431SQuinn Tran qla24xx_post_newsess_work(vha, &id,
40918777e431SQuinn Tran rptid_entry->u.f1.port_name,
40928777e431SQuinn Tran rptid_entry->u.f1.node_name,
40938777e431SQuinn Tran NULL,
40947f2a398dSQuinn Tran FS_FCP_IS_N2N);
4095edd05de1SDuane Grigsby }
4096edd05de1SDuane Grigsby
40978777e431SQuinn Tran /* if our portname is higher then initiate N2N login */
40988777e431SQuinn Tran
4099edd05de1SDuane Grigsby set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
4100edd05de1SDuane Grigsby return;
41018777e431SQuinn Tran case TOPO_FL:
41028777e431SQuinn Tran ha->current_topology = ISP_CFG_FL;
41038777e431SQuinn Tran break;
41048777e431SQuinn Tran case TOPO_F:
41058777e431SQuinn Tran ha->current_topology = ISP_CFG_F;
41068777e431SQuinn Tran break;
41078777e431SQuinn Tran default:
41088777e431SQuinn Tran break;
4109edd05de1SDuane Grigsby }
4110531a82d1SAndrew Vasquez
41119cd883f0SQuinn Tran ha->flags.gpsc_supported = 1;
41129cd883f0SQuinn Tran ha->current_topology = ISP_CFG_F;
4113969a6199SSawan Chandak /* buffer to buffer credit flag */
411441dc529aSQuinn Tran vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
4115969a6199SSawan Chandak
411641dc529aSQuinn Tran if (rptid_entry->vp_idx == 0) {
411741dc529aSQuinn Tran if (rptid_entry->vp_status == VP_STAT_COMPL) {
41187c9c4766SJoe Carnuccio /* FA-WWN is only for physical port */
411941dc529aSQuinn Tran if (qla_ini_mode_enabled(vha) &&
412041dc529aSQuinn Tran ha->flags.fawwpn_enabled &&
412141dc529aSQuinn Tran (rptid_entry->u.f1.flags &
4122fcc5b5cdSSawan Chandak BIT_6)) {
412341dc529aSQuinn Tran memcpy(vha->port_name,
412441dc529aSQuinn Tran rptid_entry->u.f1.port_name,
412541dc529aSQuinn Tran WWN_SIZE);
41267c9c4766SJoe Carnuccio }
412741dc529aSQuinn Tran
4128430eef03SQuinn Tran qla_update_host_map(vha, id);
412941dc529aSQuinn Tran }
413041dc529aSQuinn Tran
413141dc529aSQuinn Tran set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
413241dc529aSQuinn Tran set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
413341dc529aSQuinn Tran } else {
413441dc529aSQuinn Tran if (rptid_entry->vp_status != VP_STAT_COMPL &&
413541dc529aSQuinn Tran rptid_entry->vp_status != VP_STAT_ID_CHG) {
41367c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10ba,
413741dc529aSQuinn Tran "Could not acquire ID for VP[%d].\n",
413841dc529aSQuinn Tran rptid_entry->vp_idx);
41392c3dfe3fSSeokmann Ju return;
414081eb9b49SAndrew Vasquez }
41412c3dfe3fSSeokmann Ju
41424ac8d4caSAndrew Vasquez found = 0;
4143feafb7b1SArun Easi spin_lock_irqsave(&ha->vport_slock, flags);
41444ac8d4caSAndrew Vasquez list_for_each_entry(vp, &ha->vp_list, list) {
414541dc529aSQuinn Tran if (rptid_entry->vp_idx == vp->vp_idx) {
41464ac8d4caSAndrew Vasquez found = 1;
41472c3dfe3fSSeokmann Ju break;
41484ac8d4caSAndrew Vasquez }
41494ac8d4caSAndrew Vasquez }
4150feafb7b1SArun Easi spin_unlock_irqrestore(&ha->vport_slock, flags);
4151feafb7b1SArun Easi
41524ac8d4caSAndrew Vasquez if (!found)
41532c3dfe3fSSeokmann Ju return;
41542c3dfe3fSSeokmann Ju
4155430eef03SQuinn Tran qla_update_host_map(vp, id);
41562c3dfe3fSSeokmann Ju
41572c3dfe3fSSeokmann Ju /*
41582c3dfe3fSSeokmann Ju * Cannot configure here as we are still sitting on the
41592c3dfe3fSSeokmann Ju * response queue. Handle it in dpc context.
41602c3dfe3fSSeokmann Ju */
41617b867cf7SAnirban Chakraborty set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
4162531a82d1SAndrew Vasquez set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
4163531a82d1SAndrew Vasquez set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
416441dc529aSQuinn Tran }
4165531a82d1SAndrew Vasquez set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
41667b867cf7SAnirban Chakraborty qla2xxx_wake_dpc(vha);
416741dc529aSQuinn Tran } else if (rptid_entry->format == 2) {
416883548fe2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x505f,
416941dc529aSQuinn Tran "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",
417041dc529aSQuinn Tran rptid_entry->port_id[2], rptid_entry->port_id[1],
417141dc529aSQuinn Tran rptid_entry->port_id[0]);
417241dc529aSQuinn Tran
417383548fe2SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x5075,
417441dc529aSQuinn Tran "N2N: Remote WWPN %8phC.\n",
417541dc529aSQuinn Tran rptid_entry->u.f2.port_name);
417641dc529aSQuinn Tran
417741dc529aSQuinn Tran /* N2N. direct connect */
41789cd883f0SQuinn Tran ha->current_topology = ISP_CFG_N;
41799cd883f0SQuinn Tran ha->flags.rida_fmt2 = 1;
418041dc529aSQuinn Tran vha->d_id.b.domain = rptid_entry->port_id[2];
418141dc529aSQuinn Tran vha->d_id.b.area = rptid_entry->port_id[1];
418241dc529aSQuinn Tran vha->d_id.b.al_pa = rptid_entry->port_id[0];
418341dc529aSQuinn Tran
41841763c1fdSDarren Trapp ha->flags.n2n_ae = 1;
418541dc529aSQuinn Tran spin_lock_irqsave(&ha->vport_slock, flags);
4186430eef03SQuinn Tran qla_update_vp_map(vha, SET_AL_PA);
418741dc529aSQuinn Tran spin_unlock_irqrestore(&ha->vport_slock, flags);
41889cd883f0SQuinn Tran
41899cd883f0SQuinn Tran list_for_each_entry(fcport, &vha->vp_fcports, list) {
41909cd883f0SQuinn Tran fcport->scan_state = QLA_FCPORT_SCAN;
41917f2a398dSQuinn Tran fcport->n2n_flag = 0;
41929cd883f0SQuinn Tran }
41939cd883f0SQuinn Tran
41949cd883f0SQuinn Tran fcport = qla2x00_find_fcport_by_wwpn(vha,
41959cd883f0SQuinn Tran rptid_entry->u.f2.port_name, 1);
41969cd883f0SQuinn Tran
41979cd883f0SQuinn Tran if (fcport) {
419823dd98a6SQuinn Tran fcport->login_retry = vha->hw->login_retry_count;
41999cd883f0SQuinn Tran fcport->plogi_nack_done_deadline = jiffies + HZ;
42009cd883f0SQuinn Tran fcport->scan_state = QLA_FCPORT_FOUND;
4201f3f1938bSQuinn Tran fcport->keep_nport_handle = 1;
42027f2a398dSQuinn Tran fcport->n2n_flag = 1;
42037f2a398dSQuinn Tran fcport->d_id.b.domain =
42047f2a398dSQuinn Tran rptid_entry->u.f2.remote_nport_id[2];
42057f2a398dSQuinn Tran fcport->d_id.b.area =
42067f2a398dSQuinn Tran rptid_entry->u.f2.remote_nport_id[1];
42077f2a398dSQuinn Tran fcport->d_id.b.al_pa =
42087f2a398dSQuinn Tran rptid_entry->u.f2.remote_nport_id[0];
42097a8ff7d9SQuinn Tran
42107a8ff7d9SQuinn Tran /*
42117a8ff7d9SQuinn Tran * For the case where remote port sending PRLO, FW
42127a8ff7d9SQuinn Tran * sends up RIDA Format 2 as an indication of session
42137a8ff7d9SQuinn Tran * loss. In other word, FW state change from PRLI
42147a8ff7d9SQuinn Tran * complete back to PLOGI complete. Delete the
42157a8ff7d9SQuinn Tran * session and let relogin drive the reconnect.
42167a8ff7d9SQuinn Tran */
42177a8ff7d9SQuinn Tran if (atomic_read(&fcport->state) == FCS_ONLINE)
42187a8ff7d9SQuinn Tran qlt_schedule_sess_for_deletion(fcport);
42199cd883f0SQuinn Tran }
42202c3dfe3fSSeokmann Ju }
42212c3dfe3fSSeokmann Ju }
42222c3dfe3fSSeokmann Ju
42232c3dfe3fSSeokmann Ju /*
42242c3dfe3fSSeokmann Ju * qla24xx_modify_vp_config
42252c3dfe3fSSeokmann Ju * Change VP configuration for vha
42262c3dfe3fSSeokmann Ju *
42272c3dfe3fSSeokmann Ju * Input:
42282c3dfe3fSSeokmann Ju * vha = adapter block pointer.
42292c3dfe3fSSeokmann Ju *
42302c3dfe3fSSeokmann Ju * Returns:
42312c3dfe3fSSeokmann Ju * qla2xxx local function return status code.
42322c3dfe3fSSeokmann Ju *
42332c3dfe3fSSeokmann Ju * Context:
42342c3dfe3fSSeokmann Ju * Kernel context.
42352c3dfe3fSSeokmann Ju */
42362c3dfe3fSSeokmann Ju int
qla24xx_modify_vp_config(scsi_qla_host_t * vha)42372c3dfe3fSSeokmann Ju qla24xx_modify_vp_config(scsi_qla_host_t *vha)
42382c3dfe3fSSeokmann Ju {
42392c3dfe3fSSeokmann Ju int rval;
42402c3dfe3fSSeokmann Ju struct vp_config_entry_24xx *vpmod;
42412c3dfe3fSSeokmann Ju dma_addr_t vpmod_dma;
42427b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
42437b867cf7SAnirban Chakraborty struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
42442c3dfe3fSSeokmann Ju
42452c3dfe3fSSeokmann Ju /* This can be called by the parent */
42462c3dfe3fSSeokmann Ju
42475f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
42485f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
42497c3df132SSaurav Kashyap
425008eb7f45SThomas Meyer vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
42512c3dfe3fSSeokmann Ju if (!vpmod) {
42527c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0x10bc,
42537c3df132SSaurav Kashyap "Failed to allocate modify VP IOCB.\n");
42542c3dfe3fSSeokmann Ju return QLA_MEMORY_ALLOC_FAILED;
42552c3dfe3fSSeokmann Ju }
42562c3dfe3fSSeokmann Ju
42572c3dfe3fSSeokmann Ju vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
42582c3dfe3fSSeokmann Ju vpmod->entry_count = 1;
42592c3dfe3fSSeokmann Ju vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
42602c3dfe3fSSeokmann Ju vpmod->vp_count = 1;
42612c3dfe3fSSeokmann Ju vpmod->vp_index1 = vha->vp_idx;
42622c3dfe3fSSeokmann Ju vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
42632d70c103SNicholas Bellinger
42642d70c103SNicholas Bellinger qlt_modify_vp_config(vha, vpmod);
42652d70c103SNicholas Bellinger
42662c3dfe3fSSeokmann Ju memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
42672c3dfe3fSSeokmann Ju memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
42682c3dfe3fSSeokmann Ju vpmod->entry_count = 1;
42692c3dfe3fSSeokmann Ju
42707b867cf7SAnirban Chakraborty rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
42712c3dfe3fSSeokmann Ju if (rval != QLA_SUCCESS) {
42727c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10bd,
42737c3df132SSaurav Kashyap "Failed to issue VP config IOCB (%x).\n", rval);
42742c3dfe3fSSeokmann Ju } else if (vpmod->comp_status != 0) {
42757c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10be,
42767c3df132SSaurav Kashyap "Failed to complete IOCB -- error status (%x).\n",
42777c3df132SSaurav Kashyap vpmod->comp_status);
42782c3dfe3fSSeokmann Ju rval = QLA_FUNCTION_FAILED;
4279ad950360SBart Van Assche } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
42807c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10bf,
42817c3df132SSaurav Kashyap "Failed to complete IOCB -- completion status (%x).\n",
42827c3df132SSaurav Kashyap le16_to_cpu(vpmod->comp_status));
42832c3dfe3fSSeokmann Ju rval = QLA_FUNCTION_FAILED;
42842c3dfe3fSSeokmann Ju } else {
42852c3dfe3fSSeokmann Ju /* EMPTY */
42865f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
42875f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
42882c3dfe3fSSeokmann Ju fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
42892c3dfe3fSSeokmann Ju }
42907b867cf7SAnirban Chakraborty dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
42912c3dfe3fSSeokmann Ju
42922c3dfe3fSSeokmann Ju return rval;
42932c3dfe3fSSeokmann Ju }
42942c3dfe3fSSeokmann Ju
42952c3dfe3fSSeokmann Ju /*
42962c3dfe3fSSeokmann Ju * qla2x00_send_change_request
42972c3dfe3fSSeokmann Ju * Receive or disable RSCN request from fabric controller
42982c3dfe3fSSeokmann Ju *
42992c3dfe3fSSeokmann Ju * Input:
43002c3dfe3fSSeokmann Ju * ha = adapter block pointer
43012c3dfe3fSSeokmann Ju * format = registration format:
43022c3dfe3fSSeokmann Ju * 0 - Reserved
43032c3dfe3fSSeokmann Ju * 1 - Fabric detected registration
43042c3dfe3fSSeokmann Ju * 2 - N_port detected registration
43052c3dfe3fSSeokmann Ju * 3 - Full registration
43062c3dfe3fSSeokmann Ju * FF - clear registration
43072c3dfe3fSSeokmann Ju * vp_idx = Virtual port index
43082c3dfe3fSSeokmann Ju *
43092c3dfe3fSSeokmann Ju * Returns:
43102c3dfe3fSSeokmann Ju * qla2x00 local function return status code.
43112c3dfe3fSSeokmann Ju *
43122c3dfe3fSSeokmann Ju * Context:
43132c3dfe3fSSeokmann Ju * Kernel Context
43142c3dfe3fSSeokmann Ju */
43152c3dfe3fSSeokmann Ju
43162c3dfe3fSSeokmann Ju int
qla2x00_send_change_request(scsi_qla_host_t * vha,uint16_t format,uint16_t vp_idx)43177b867cf7SAnirban Chakraborty qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
43182c3dfe3fSSeokmann Ju uint16_t vp_idx)
43192c3dfe3fSSeokmann Ju {
43202c3dfe3fSSeokmann Ju int rval;
43212c3dfe3fSSeokmann Ju mbx_cmd_t mc;
43222c3dfe3fSSeokmann Ju mbx_cmd_t *mcp = &mc;
43232c3dfe3fSSeokmann Ju
43245f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
43255f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
43267c3df132SSaurav Kashyap
43272c3dfe3fSSeokmann Ju mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
43282c3dfe3fSSeokmann Ju mcp->mb[1] = format;
43292c3dfe3fSSeokmann Ju mcp->mb[9] = vp_idx;
43302c3dfe3fSSeokmann Ju mcp->out_mb = MBX_9|MBX_1|MBX_0;
43312c3dfe3fSSeokmann Ju mcp->in_mb = MBX_0|MBX_1;
43322c3dfe3fSSeokmann Ju mcp->tov = MBX_TOV_SECONDS;
43332c3dfe3fSSeokmann Ju mcp->flags = 0;
43347b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
43352c3dfe3fSSeokmann Ju
43362c3dfe3fSSeokmann Ju if (rval == QLA_SUCCESS) {
43372c3dfe3fSSeokmann Ju if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
43382c3dfe3fSSeokmann Ju rval = BIT_1;
43392c3dfe3fSSeokmann Ju }
43402c3dfe3fSSeokmann Ju } else
43412c3dfe3fSSeokmann Ju rval = BIT_1;
43422c3dfe3fSSeokmann Ju
43432c3dfe3fSSeokmann Ju return rval;
43442c3dfe3fSSeokmann Ju }
4345338c9161SAndrew Vasquez
4346338c9161SAndrew Vasquez int
qla2x00_dump_ram(scsi_qla_host_t * vha,dma_addr_t req_dma,uint32_t addr,uint32_t size)43477b867cf7SAnirban Chakraborty qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
4348338c9161SAndrew Vasquez uint32_t size)
4349338c9161SAndrew Vasquez {
4350338c9161SAndrew Vasquez int rval;
4351338c9161SAndrew Vasquez mbx_cmd_t mc;
4352338c9161SAndrew Vasquez mbx_cmd_t *mcp = &mc;
4353338c9161SAndrew Vasquez
43545f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
43555f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
4356338c9161SAndrew Vasquez
43577b867cf7SAnirban Chakraborty if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
4358338c9161SAndrew Vasquez mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
4359338c9161SAndrew Vasquez mcp->mb[8] = MSW(addr);
4360044c218bSQuinn Tran mcp->mb[10] = 0;
4361044c218bSQuinn Tran mcp->out_mb = MBX_10|MBX_8|MBX_0;
4362338c9161SAndrew Vasquez } else {
4363338c9161SAndrew Vasquez mcp->mb[0] = MBC_DUMP_RISC_RAM;
4364338c9161SAndrew Vasquez mcp->out_mb = MBX_0;
4365338c9161SAndrew Vasquez }
4366338c9161SAndrew Vasquez mcp->mb[1] = LSW(addr);
4367338c9161SAndrew Vasquez mcp->mb[2] = MSW(req_dma);
4368338c9161SAndrew Vasquez mcp->mb[3] = LSW(req_dma);
4369338c9161SAndrew Vasquez mcp->mb[6] = MSW(MSD(req_dma));
4370338c9161SAndrew Vasquez mcp->mb[7] = LSW(MSD(req_dma));
4371338c9161SAndrew Vasquez mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
43727b867cf7SAnirban Chakraborty if (IS_FWI2_CAPABLE(vha->hw)) {
4373338c9161SAndrew Vasquez mcp->mb[4] = MSW(size);
4374338c9161SAndrew Vasquez mcp->mb[5] = LSW(size);
4375338c9161SAndrew Vasquez mcp->out_mb |= MBX_5|MBX_4;
4376338c9161SAndrew Vasquez } else {
4377338c9161SAndrew Vasquez mcp->mb[4] = LSW(size);
4378338c9161SAndrew Vasquez mcp->out_mb |= MBX_4;
4379338c9161SAndrew Vasquez }
4380338c9161SAndrew Vasquez
4381338c9161SAndrew Vasquez mcp->in_mb = MBX_0;
4382b93480e3SRavi Anand mcp->tov = MBX_TOV_SECONDS;
4383338c9161SAndrew Vasquez mcp->flags = 0;
43847b867cf7SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
4385338c9161SAndrew Vasquez
4386338c9161SAndrew Vasquez if (rval != QLA_SUCCESS) {
43877c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1008,
43887c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4389338c9161SAndrew Vasquez } else {
43905f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
43915f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
4392338c9161SAndrew Vasquez }
4393338c9161SAndrew Vasquez
4394338c9161SAndrew Vasquez return rval;
4395338c9161SAndrew Vasquez }
43964d4df193SHarihara Kadayam /* 84XX Support **************************************************************/
43974d4df193SHarihara Kadayam
43984d4df193SHarihara Kadayam struct cs84xx_mgmt_cmd {
43994d4df193SHarihara Kadayam union {
44004d4df193SHarihara Kadayam struct verify_chip_entry_84xx req;
44014d4df193SHarihara Kadayam struct verify_chip_rsp_84xx rsp;
44024d4df193SHarihara Kadayam } p;
44034d4df193SHarihara Kadayam };
44044d4df193SHarihara Kadayam
44054d4df193SHarihara Kadayam int
qla84xx_verify_chip(struct scsi_qla_host * vha,uint16_t * status)44067b867cf7SAnirban Chakraborty qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
44074d4df193SHarihara Kadayam {
44084d4df193SHarihara Kadayam int rval, retry;
44094d4df193SHarihara Kadayam struct cs84xx_mgmt_cmd *mn;
44104d4df193SHarihara Kadayam dma_addr_t mn_dma;
44114d4df193SHarihara Kadayam uint16_t options;
44124d4df193SHarihara Kadayam unsigned long flags;
44137b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
44144d4df193SHarihara Kadayam
44155f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
44165f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
44174d4df193SHarihara Kadayam
44184d4df193SHarihara Kadayam mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
44194d4df193SHarihara Kadayam if (mn == NULL) {
44204d4df193SHarihara Kadayam return QLA_MEMORY_ALLOC_FAILED;
44214d4df193SHarihara Kadayam }
44224d4df193SHarihara Kadayam
44234d4df193SHarihara Kadayam /* Force Update? */
44244d4df193SHarihara Kadayam options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
44254d4df193SHarihara Kadayam /* Diagnostic firmware? */
44264d4df193SHarihara Kadayam /* options |= MENLO_DIAG_FW; */
44274d4df193SHarihara Kadayam /* We update the firmware with only one data sequence. */
44284d4df193SHarihara Kadayam options |= VCO_END_OF_DATA;
44294d4df193SHarihara Kadayam
44304d4df193SHarihara Kadayam do {
4431c1ec1f1bSAndrew Vasquez retry = 0;
44324d4df193SHarihara Kadayam memset(mn, 0, sizeof(*mn));
44334d4df193SHarihara Kadayam mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
44344d4df193SHarihara Kadayam mn->p.req.entry_count = 1;
44354d4df193SHarihara Kadayam mn->p.req.options = cpu_to_le16(options);
44364d4df193SHarihara Kadayam
44377c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
44387c3df132SSaurav Kashyap "Dump of Verify Request.\n");
44397c3df132SSaurav Kashyap ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
4440f8f97b0cSJoe Carnuccio mn, sizeof(*mn));
44414d4df193SHarihara Kadayam
44427b867cf7SAnirban Chakraborty rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
44434d4df193SHarihara Kadayam if (rval != QLA_SUCCESS) {
44447c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10cb,
44457c3df132SSaurav Kashyap "Failed to issue verify IOCB (%x).\n", rval);
44464d4df193SHarihara Kadayam goto verify_done;
44474d4df193SHarihara Kadayam }
44484d4df193SHarihara Kadayam
44497c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
44507c3df132SSaurav Kashyap "Dump of Verify Response.\n");
44517c3df132SSaurav Kashyap ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
4452f8f97b0cSJoe Carnuccio mn, sizeof(*mn));
44534d4df193SHarihara Kadayam
44544d4df193SHarihara Kadayam status[0] = le16_to_cpu(mn->p.rsp.comp_status);
44554d4df193SHarihara Kadayam status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
44564d4df193SHarihara Kadayam le16_to_cpu(mn->p.rsp.failure_code) : 0;
44575f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
44587c3df132SSaurav Kashyap "cs=%x fc=%x.\n", status[0], status[1]);
44594d4df193SHarihara Kadayam
44604d4df193SHarihara Kadayam if (status[0] != CS_COMPLETE) {
44614d4df193SHarihara Kadayam rval = QLA_FUNCTION_FAILED;
44624d4df193SHarihara Kadayam if (!(options & VCO_DONT_UPDATE_FW)) {
44637c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10cf,
44647c3df132SSaurav Kashyap "Firmware update failed. Retrying "
44657c3df132SSaurav Kashyap "without update firmware.\n");
44664d4df193SHarihara Kadayam options |= VCO_DONT_UPDATE_FW;
44674d4df193SHarihara Kadayam options &= ~VCO_FORCE_UPDATE;
44684d4df193SHarihara Kadayam retry = 1;
44694d4df193SHarihara Kadayam }
44704d4df193SHarihara Kadayam } else {
44715f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
44727c3df132SSaurav Kashyap "Firmware updated to %x.\n",
44737c3df132SSaurav Kashyap le32_to_cpu(mn->p.rsp.fw_ver));
44744d4df193SHarihara Kadayam
44754d4df193SHarihara Kadayam /* NOTE: we only update OP firmware. */
44764d4df193SHarihara Kadayam spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
44774d4df193SHarihara Kadayam ha->cs84xx->op_fw_version =
44784d4df193SHarihara Kadayam le32_to_cpu(mn->p.rsp.fw_ver);
44794d4df193SHarihara Kadayam spin_unlock_irqrestore(&ha->cs84xx->access_lock,
44804d4df193SHarihara Kadayam flags);
44814d4df193SHarihara Kadayam }
44824d4df193SHarihara Kadayam } while (retry);
44834d4df193SHarihara Kadayam
44844d4df193SHarihara Kadayam verify_done:
44854d4df193SHarihara Kadayam dma_pool_free(ha->s_dma_pool, mn, mn_dma);
44864d4df193SHarihara Kadayam
44874d4df193SHarihara Kadayam if (rval != QLA_SUCCESS) {
44885f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10d1,
44895f28d2d7SSaurav Kashyap "Failed=%x.\n", rval);
44904d4df193SHarihara Kadayam } else {
44915f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
44925f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
44934d4df193SHarihara Kadayam }
44944d4df193SHarihara Kadayam
44954d4df193SHarihara Kadayam return rval;
44964d4df193SHarihara Kadayam }
449773208dfdSAnirban Chakraborty
449873208dfdSAnirban Chakraborty int
qla25xx_init_req_que(struct scsi_qla_host * vha,struct req_que * req)4499618a7523SAnirban Chakraborty qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
450073208dfdSAnirban Chakraborty {
450173208dfdSAnirban Chakraborty int rval;
450273208dfdSAnirban Chakraborty unsigned long flags;
450373208dfdSAnirban Chakraborty mbx_cmd_t mc;
450473208dfdSAnirban Chakraborty mbx_cmd_t *mcp = &mc;
450573208dfdSAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
450673208dfdSAnirban Chakraborty
450745235022SQuinn Tran if (!ha->flags.fw_started)
450845235022SQuinn Tran return QLA_SUCCESS;
450945235022SQuinn Tran
45105f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
45115f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
45127c3df132SSaurav Kashyap
45137c6300e3SJoe Carnuccio if (IS_SHADOW_REG_CAPABLE(ha))
45147c6300e3SJoe Carnuccio req->options |= BIT_13;
45157c6300e3SJoe Carnuccio
451673208dfdSAnirban Chakraborty mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
4517618a7523SAnirban Chakraborty mcp->mb[1] = req->options;
451873208dfdSAnirban Chakraborty mcp->mb[2] = MSW(LSD(req->dma));
451973208dfdSAnirban Chakraborty mcp->mb[3] = LSW(LSD(req->dma));
452073208dfdSAnirban Chakraborty mcp->mb[6] = MSW(MSD(req->dma));
452173208dfdSAnirban Chakraborty mcp->mb[7] = LSW(MSD(req->dma));
452273208dfdSAnirban Chakraborty mcp->mb[5] = req->length;
452373208dfdSAnirban Chakraborty if (req->rsp)
452473208dfdSAnirban Chakraborty mcp->mb[10] = req->rsp->id;
452573208dfdSAnirban Chakraborty mcp->mb[12] = req->qos;
452673208dfdSAnirban Chakraborty mcp->mb[11] = req->vp_idx;
452773208dfdSAnirban Chakraborty mcp->mb[13] = req->rid;
4528ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
45296246b8a1SGiridhar Malavali mcp->mb[15] = 0;
453073208dfdSAnirban Chakraborty
453173208dfdSAnirban Chakraborty mcp->mb[4] = req->id;
453273208dfdSAnirban Chakraborty /* que in ptr index */
453373208dfdSAnirban Chakraborty mcp->mb[8] = 0;
453473208dfdSAnirban Chakraborty /* que out ptr index */
45357c6300e3SJoe Carnuccio mcp->mb[9] = *req->out_ptr = 0;
453673208dfdSAnirban Chakraborty mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
453773208dfdSAnirban Chakraborty MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
453873208dfdSAnirban Chakraborty mcp->in_mb = MBX_0;
453973208dfdSAnirban Chakraborty mcp->flags = MBX_DMA_OUT;
45406246b8a1SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS * 2;
45416246b8a1SGiridhar Malavali
4542ecc89f25SJoe Carnuccio if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
4543ecc89f25SJoe Carnuccio IS_QLA28XX(ha))
45446246b8a1SGiridhar Malavali mcp->in_mb |= MBX_1;
4545ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
45466246b8a1SGiridhar Malavali mcp->out_mb |= MBX_15;
45476246b8a1SGiridhar Malavali /* debug q create issue in SR-IOV */
45486246b8a1SGiridhar Malavali mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
45496246b8a1SGiridhar Malavali }
455073208dfdSAnirban Chakraborty
455173208dfdSAnirban Chakraborty spin_lock_irqsave(&ha->hardware_lock, flags);
4552618a7523SAnirban Chakraborty if (!(req->options & BIT_0)) {
455304474d3aSBart Van Assche wrt_reg_dword(req->req_q_in, 0);
4554ecc89f25SJoe Carnuccio if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
455504474d3aSBart Van Assche wrt_reg_dword(req->req_q_out, 0);
455673208dfdSAnirban Chakraborty }
455773208dfdSAnirban Chakraborty spin_unlock_irqrestore(&ha->hardware_lock, flags);
455873208dfdSAnirban Chakraborty
455917d98630SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
45607c3df132SSaurav Kashyap if (rval != QLA_SUCCESS) {
45617c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10d4,
45627c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
45637c3df132SSaurav Kashyap } else {
45645f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
45655f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
45667c3df132SSaurav Kashyap }
45677c3df132SSaurav Kashyap
456873208dfdSAnirban Chakraborty return rval;
456973208dfdSAnirban Chakraborty }
457073208dfdSAnirban Chakraborty
457173208dfdSAnirban Chakraborty int
qla25xx_init_rsp_que(struct scsi_qla_host * vha,struct rsp_que * rsp)4572618a7523SAnirban Chakraborty qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
457373208dfdSAnirban Chakraborty {
457473208dfdSAnirban Chakraborty int rval;
457573208dfdSAnirban Chakraborty unsigned long flags;
457673208dfdSAnirban Chakraborty mbx_cmd_t mc;
457773208dfdSAnirban Chakraborty mbx_cmd_t *mcp = &mc;
457873208dfdSAnirban Chakraborty struct qla_hw_data *ha = vha->hw;
457973208dfdSAnirban Chakraborty
458045235022SQuinn Tran if (!ha->flags.fw_started)
458145235022SQuinn Tran return QLA_SUCCESS;
458245235022SQuinn Tran
45835f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
45845f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
45857c3df132SSaurav Kashyap
45867c6300e3SJoe Carnuccio if (IS_SHADOW_REG_CAPABLE(ha))
45877c6300e3SJoe Carnuccio rsp->options |= BIT_13;
45887c6300e3SJoe Carnuccio
458973208dfdSAnirban Chakraborty mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
4590618a7523SAnirban Chakraborty mcp->mb[1] = rsp->options;
459173208dfdSAnirban Chakraborty mcp->mb[2] = MSW(LSD(rsp->dma));
459273208dfdSAnirban Chakraborty mcp->mb[3] = LSW(LSD(rsp->dma));
459373208dfdSAnirban Chakraborty mcp->mb[6] = MSW(MSD(rsp->dma));
459473208dfdSAnirban Chakraborty mcp->mb[7] = LSW(MSD(rsp->dma));
459573208dfdSAnirban Chakraborty mcp->mb[5] = rsp->length;
4596444786d7SAndrew Vasquez mcp->mb[14] = rsp->msix->entry;
459773208dfdSAnirban Chakraborty mcp->mb[13] = rsp->rid;
4598ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
45996246b8a1SGiridhar Malavali mcp->mb[15] = 0;
460073208dfdSAnirban Chakraborty
460173208dfdSAnirban Chakraborty mcp->mb[4] = rsp->id;
460273208dfdSAnirban Chakraborty /* que in ptr index */
46037c6300e3SJoe Carnuccio mcp->mb[8] = *rsp->in_ptr = 0;
460473208dfdSAnirban Chakraborty /* que out ptr index */
460573208dfdSAnirban Chakraborty mcp->mb[9] = 0;
46062afa19a9SAnirban Chakraborty mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
460773208dfdSAnirban Chakraborty |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
460873208dfdSAnirban Chakraborty mcp->in_mb = MBX_0;
460973208dfdSAnirban Chakraborty mcp->flags = MBX_DMA_OUT;
46106246b8a1SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS * 2;
46116246b8a1SGiridhar Malavali
46126246b8a1SGiridhar Malavali if (IS_QLA81XX(ha)) {
46136246b8a1SGiridhar Malavali mcp->out_mb |= MBX_12|MBX_11|MBX_10;
46146246b8a1SGiridhar Malavali mcp->in_mb |= MBX_1;
4615ecc89f25SJoe Carnuccio } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
46166246b8a1SGiridhar Malavali mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
46176246b8a1SGiridhar Malavali mcp->in_mb |= MBX_1;
46186246b8a1SGiridhar Malavali /* debug q create issue in SR-IOV */
46196246b8a1SGiridhar Malavali mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
46206246b8a1SGiridhar Malavali }
462173208dfdSAnirban Chakraborty
462273208dfdSAnirban Chakraborty spin_lock_irqsave(&ha->hardware_lock, flags);
4623618a7523SAnirban Chakraborty if (!(rsp->options & BIT_0)) {
462404474d3aSBart Van Assche wrt_reg_dword(rsp->rsp_q_out, 0);
4625ecc89f25SJoe Carnuccio if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
462604474d3aSBart Van Assche wrt_reg_dword(rsp->rsp_q_in, 0);
462773208dfdSAnirban Chakraborty }
462873208dfdSAnirban Chakraborty
462973208dfdSAnirban Chakraborty spin_unlock_irqrestore(&ha->hardware_lock, flags);
463073208dfdSAnirban Chakraborty
463117d98630SAnirban Chakraborty rval = qla2x00_mailbox_command(vha, mcp);
46327c3df132SSaurav Kashyap if (rval != QLA_SUCCESS) {
46337c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10d7,
46347c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
46357c3df132SSaurav Kashyap } else {
46365f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
46375f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
46387c3df132SSaurav Kashyap }
46397c3df132SSaurav Kashyap
464073208dfdSAnirban Chakraborty return rval;
464173208dfdSAnirban Chakraborty }
464273208dfdSAnirban Chakraborty
46438a659571SAndrew Vasquez int
qla81xx_idc_ack(scsi_qla_host_t * vha,uint16_t * mb)46448a659571SAndrew Vasquez qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
46458a659571SAndrew Vasquez {
46468a659571SAndrew Vasquez int rval;
46478a659571SAndrew Vasquez mbx_cmd_t mc;
46488a659571SAndrew Vasquez mbx_cmd_t *mcp = &mc;
46498a659571SAndrew Vasquez
46505f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
46515f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
46528a659571SAndrew Vasquez
46538a659571SAndrew Vasquez mcp->mb[0] = MBC_IDC_ACK;
46548a659571SAndrew Vasquez memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
46558a659571SAndrew Vasquez mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
46568a659571SAndrew Vasquez mcp->in_mb = MBX_0;
46578a659571SAndrew Vasquez mcp->tov = MBX_TOV_SECONDS;
46588a659571SAndrew Vasquez mcp->flags = 0;
46598a659571SAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
46608a659571SAndrew Vasquez
46618a659571SAndrew Vasquez if (rval != QLA_SUCCESS) {
46627c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10da,
46637c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
46648a659571SAndrew Vasquez } else {
46655f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
46665f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
46678a659571SAndrew Vasquez }
46688a659571SAndrew Vasquez
46698a659571SAndrew Vasquez return rval;
46708a659571SAndrew Vasquez }
46711d2874deSJoe Carnuccio
46721d2874deSJoe Carnuccio int
qla81xx_fac_get_sector_size(scsi_qla_host_t * vha,uint32_t * sector_size)46731d2874deSJoe Carnuccio qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
46741d2874deSJoe Carnuccio {
46751d2874deSJoe Carnuccio int rval;
46761d2874deSJoe Carnuccio mbx_cmd_t mc;
46771d2874deSJoe Carnuccio mbx_cmd_t *mcp = &mc;
46781d2874deSJoe Carnuccio
46795f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
46805f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
46817c3df132SSaurav Kashyap
4682f73cb695SChad Dupuis if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4683ecc89f25SJoe Carnuccio !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))
46841d2874deSJoe Carnuccio return QLA_FUNCTION_FAILED;
46851d2874deSJoe Carnuccio
46861d2874deSJoe Carnuccio mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
46871d2874deSJoe Carnuccio mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
46881d2874deSJoe Carnuccio mcp->out_mb = MBX_1|MBX_0;
46891d2874deSJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
46901d2874deSJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
46911d2874deSJoe Carnuccio mcp->flags = 0;
46921d2874deSJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
46931d2874deSJoe Carnuccio
46941d2874deSJoe Carnuccio if (rval != QLA_SUCCESS) {
46957c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10dd,
46967c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
46977c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
46981d2874deSJoe Carnuccio } else {
46995f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
47005f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
47011d2874deSJoe Carnuccio *sector_size = mcp->mb[1];
47021d2874deSJoe Carnuccio }
47031d2874deSJoe Carnuccio
47041d2874deSJoe Carnuccio return rval;
47051d2874deSJoe Carnuccio }
47061d2874deSJoe Carnuccio
47071d2874deSJoe Carnuccio int
qla81xx_fac_do_write_enable(scsi_qla_host_t * vha,int enable)47081d2874deSJoe Carnuccio qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
47091d2874deSJoe Carnuccio {
47101d2874deSJoe Carnuccio int rval;
47111d2874deSJoe Carnuccio mbx_cmd_t mc;
47121d2874deSJoe Carnuccio mbx_cmd_t *mcp = &mc;
47131d2874deSJoe Carnuccio
4714f73cb695SChad Dupuis if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4715ecc89f25SJoe Carnuccio !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))
47161d2874deSJoe Carnuccio return QLA_FUNCTION_FAILED;
47171d2874deSJoe Carnuccio
47185f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
47195f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
47201d2874deSJoe Carnuccio
47211d2874deSJoe Carnuccio mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
47221d2874deSJoe Carnuccio mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
47231d2874deSJoe Carnuccio FAC_OPT_CMD_WRITE_PROTECT;
47241d2874deSJoe Carnuccio mcp->out_mb = MBX_1|MBX_0;
47251d2874deSJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
47261d2874deSJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
47271d2874deSJoe Carnuccio mcp->flags = 0;
47281d2874deSJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
47291d2874deSJoe Carnuccio
47301d2874deSJoe Carnuccio if (rval != QLA_SUCCESS) {
47317c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10e0,
47327c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
47337c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
47341d2874deSJoe Carnuccio } else {
47355f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
47365f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
47371d2874deSJoe Carnuccio }
47381d2874deSJoe Carnuccio
47391d2874deSJoe Carnuccio return rval;
47401d2874deSJoe Carnuccio }
47411d2874deSJoe Carnuccio
47421d2874deSJoe Carnuccio int
qla81xx_fac_erase_sector(scsi_qla_host_t * vha,uint32_t start,uint32_t finish)47431d2874deSJoe Carnuccio qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
47441d2874deSJoe Carnuccio {
47451d2874deSJoe Carnuccio int rval;
47461d2874deSJoe Carnuccio mbx_cmd_t mc;
47471d2874deSJoe Carnuccio mbx_cmd_t *mcp = &mc;
47481d2874deSJoe Carnuccio
4749f73cb695SChad Dupuis if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4750ecc89f25SJoe Carnuccio !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))
47511d2874deSJoe Carnuccio return QLA_FUNCTION_FAILED;
47521d2874deSJoe Carnuccio
47535f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
47545f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
47551d2874deSJoe Carnuccio
47561d2874deSJoe Carnuccio mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
47571d2874deSJoe Carnuccio mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
47581d2874deSJoe Carnuccio mcp->mb[2] = LSW(start);
47591d2874deSJoe Carnuccio mcp->mb[3] = MSW(start);
47601d2874deSJoe Carnuccio mcp->mb[4] = LSW(finish);
47611d2874deSJoe Carnuccio mcp->mb[5] = MSW(finish);
47621d2874deSJoe Carnuccio mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
47631d2874deSJoe Carnuccio mcp->in_mb = MBX_2|MBX_1|MBX_0;
47641d2874deSJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
47651d2874deSJoe Carnuccio mcp->flags = 0;
47661d2874deSJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
47671d2874deSJoe Carnuccio
47681d2874deSJoe Carnuccio if (rval != QLA_SUCCESS) {
47697c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10e3,
47707c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
47717c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
47721d2874deSJoe Carnuccio } else {
47735f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
47745f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
47751d2874deSJoe Carnuccio }
47761d2874deSJoe Carnuccio
47771d2874deSJoe Carnuccio return rval;
47781d2874deSJoe Carnuccio }
47796e181be5SLalit Chandivade
47806e181be5SLalit Chandivade int
qla81xx_fac_semaphore_access(scsi_qla_host_t * vha,int lock)47813f006ac3SMichael Hernandez qla81xx_fac_semaphore_access(scsi_qla_host_t *vha, int lock)
47823f006ac3SMichael Hernandez {
47833f006ac3SMichael Hernandez int rval = QLA_SUCCESS;
47843f006ac3SMichael Hernandez mbx_cmd_t mc;
47853f006ac3SMichael Hernandez mbx_cmd_t *mcp = &mc;
47863f006ac3SMichael Hernandez struct qla_hw_data *ha = vha->hw;
47873f006ac3SMichael Hernandez
47883f006ac3SMichael Hernandez if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
47893f006ac3SMichael Hernandez !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
47903f006ac3SMichael Hernandez return rval;
47913f006ac3SMichael Hernandez
47923f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
47933f006ac3SMichael Hernandez "Entered %s.\n", __func__);
47943f006ac3SMichael Hernandez
47953f006ac3SMichael Hernandez mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
47963f006ac3SMichael Hernandez mcp->mb[1] = (lock ? FAC_OPT_CMD_LOCK_SEMAPHORE :
47973f006ac3SMichael Hernandez FAC_OPT_CMD_UNLOCK_SEMAPHORE);
47983f006ac3SMichael Hernandez mcp->out_mb = MBX_1|MBX_0;
47993f006ac3SMichael Hernandez mcp->in_mb = MBX_1|MBX_0;
48003f006ac3SMichael Hernandez mcp->tov = MBX_TOV_SECONDS;
48013f006ac3SMichael Hernandez mcp->flags = 0;
48023f006ac3SMichael Hernandez rval = qla2x00_mailbox_command(vha, mcp);
48033f006ac3SMichael Hernandez
48043f006ac3SMichael Hernandez if (rval != QLA_SUCCESS) {
48053f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx, vha, 0x10e3,
48063f006ac3SMichael Hernandez "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
48073f006ac3SMichael Hernandez rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
48083f006ac3SMichael Hernandez } else {
48093f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
48103f006ac3SMichael Hernandez "Done %s.\n", __func__);
48113f006ac3SMichael Hernandez }
48123f006ac3SMichael Hernandez
48133f006ac3SMichael Hernandez return rval;
48143f006ac3SMichael Hernandez }
48153f006ac3SMichael Hernandez
48163f006ac3SMichael Hernandez int
qla81xx_restart_mpi_firmware(scsi_qla_host_t * vha)48176e181be5SLalit Chandivade qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
48186e181be5SLalit Chandivade {
48196e181be5SLalit Chandivade int rval = 0;
48206e181be5SLalit Chandivade mbx_cmd_t mc;
48216e181be5SLalit Chandivade mbx_cmd_t *mcp = &mc;
48226e181be5SLalit Chandivade
48235f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
48245f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
48256e181be5SLalit Chandivade
48266e181be5SLalit Chandivade mcp->mb[0] = MBC_RESTART_MPI_FW;
48276e181be5SLalit Chandivade mcp->out_mb = MBX_0;
48286e181be5SLalit Chandivade mcp->in_mb = MBX_0|MBX_1;
48296e181be5SLalit Chandivade mcp->tov = MBX_TOV_SECONDS;
48306e181be5SLalit Chandivade mcp->flags = 0;
48316e181be5SLalit Chandivade rval = qla2x00_mailbox_command(vha, mcp);
48326e181be5SLalit Chandivade
48336e181be5SLalit Chandivade if (rval != QLA_SUCCESS) {
48347c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10e6,
48357c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
48367c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
48376e181be5SLalit Chandivade } else {
48385f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
48395f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
48406e181be5SLalit Chandivade }
48416e181be5SLalit Chandivade
48426e181be5SLalit Chandivade return rval;
48436e181be5SLalit Chandivade }
4844ad0ecd61SJoe Carnuccio
4845c46e65c7SJoe Carnuccio int
qla82xx_set_driver_version(scsi_qla_host_t * vha,char * version)4846c46e65c7SJoe Carnuccio qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4847c46e65c7SJoe Carnuccio {
4848c46e65c7SJoe Carnuccio int rval;
4849c46e65c7SJoe Carnuccio mbx_cmd_t mc;
4850c46e65c7SJoe Carnuccio mbx_cmd_t *mcp = &mc;
4851c46e65c7SJoe Carnuccio int i;
4852c46e65c7SJoe Carnuccio int len;
48537ffa5b93SBart Van Assche __le16 *str;
4854c46e65c7SJoe Carnuccio struct qla_hw_data *ha = vha->hw;
4855c46e65c7SJoe Carnuccio
4856c46e65c7SJoe Carnuccio if (!IS_P3P_TYPE(ha))
4857c46e65c7SJoe Carnuccio return QLA_FUNCTION_FAILED;
4858c46e65c7SJoe Carnuccio
4859c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4860c46e65c7SJoe Carnuccio "Entered %s.\n", __func__);
4861c46e65c7SJoe Carnuccio
48627ffa5b93SBart Van Assche str = (__force __le16 *)version;
4863c46e65c7SJoe Carnuccio len = strlen(version);
4864c46e65c7SJoe Carnuccio
4865c46e65c7SJoe Carnuccio mcp->mb[0] = MBC_SET_RNID_PARAMS;
4866c46e65c7SJoe Carnuccio mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4867c46e65c7SJoe Carnuccio mcp->out_mb = MBX_1|MBX_0;
4868c46e65c7SJoe Carnuccio for (i = 4; i < 16 && len; i++, str++, len -= 2) {
48697ffa5b93SBart Van Assche mcp->mb[i] = le16_to_cpup(str);
4870c46e65c7SJoe Carnuccio mcp->out_mb |= 1<<i;
4871c46e65c7SJoe Carnuccio }
4872c46e65c7SJoe Carnuccio for (; i < 16; i++) {
4873c46e65c7SJoe Carnuccio mcp->mb[i] = 0;
4874c46e65c7SJoe Carnuccio mcp->out_mb |= 1<<i;
4875c46e65c7SJoe Carnuccio }
4876c46e65c7SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
4877c46e65c7SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
4878c46e65c7SJoe Carnuccio mcp->flags = 0;
4879c46e65c7SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
4880c46e65c7SJoe Carnuccio
4881c46e65c7SJoe Carnuccio if (rval != QLA_SUCCESS) {
4882c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x117c,
4883c46e65c7SJoe Carnuccio "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4884c46e65c7SJoe Carnuccio } else {
4885c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4886c46e65c7SJoe Carnuccio "Done %s.\n", __func__);
4887c46e65c7SJoe Carnuccio }
4888c46e65c7SJoe Carnuccio
4889c46e65c7SJoe Carnuccio return rval;
4890c46e65c7SJoe Carnuccio }
4891c46e65c7SJoe Carnuccio
4892c46e65c7SJoe Carnuccio int
qla25xx_set_driver_version(scsi_qla_host_t * vha,char * version)4893c46e65c7SJoe Carnuccio qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4894c46e65c7SJoe Carnuccio {
4895c46e65c7SJoe Carnuccio int rval;
4896c46e65c7SJoe Carnuccio mbx_cmd_t mc;
4897c46e65c7SJoe Carnuccio mbx_cmd_t *mcp = &mc;
4898c46e65c7SJoe Carnuccio int len;
4899c46e65c7SJoe Carnuccio uint16_t dwlen;
4900c46e65c7SJoe Carnuccio uint8_t *str;
4901c46e65c7SJoe Carnuccio dma_addr_t str_dma;
4902c46e65c7SJoe Carnuccio struct qla_hw_data *ha = vha->hw;
4903c46e65c7SJoe Carnuccio
4904c46e65c7SJoe Carnuccio if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4905c46e65c7SJoe Carnuccio IS_P3P_TYPE(ha))
4906c46e65c7SJoe Carnuccio return QLA_FUNCTION_FAILED;
4907c46e65c7SJoe Carnuccio
4908c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4909c46e65c7SJoe Carnuccio "Entered %s.\n", __func__);
4910c46e65c7SJoe Carnuccio
4911c46e65c7SJoe Carnuccio str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4912c46e65c7SJoe Carnuccio if (!str) {
4913c46e65c7SJoe Carnuccio ql_log(ql_log_warn, vha, 0x117f,
4914c46e65c7SJoe Carnuccio "Failed to allocate driver version param.\n");
4915c46e65c7SJoe Carnuccio return QLA_MEMORY_ALLOC_FAILED;
4916c46e65c7SJoe Carnuccio }
4917c46e65c7SJoe Carnuccio
4918c46e65c7SJoe Carnuccio memcpy(str, "\x7\x3\x11\x0", 4);
4919c46e65c7SJoe Carnuccio dwlen = str[0];
4920c46e65c7SJoe Carnuccio len = dwlen * 4 - 4;
4921c46e65c7SJoe Carnuccio memset(str + 4, 0, len);
4922c46e65c7SJoe Carnuccio if (len > strlen(version))
4923c46e65c7SJoe Carnuccio len = strlen(version);
4924c46e65c7SJoe Carnuccio memcpy(str + 4, version, len);
4925c46e65c7SJoe Carnuccio
4926c46e65c7SJoe Carnuccio mcp->mb[0] = MBC_SET_RNID_PARAMS;
4927c46e65c7SJoe Carnuccio mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4928c46e65c7SJoe Carnuccio mcp->mb[2] = MSW(LSD(str_dma));
4929c46e65c7SJoe Carnuccio mcp->mb[3] = LSW(LSD(str_dma));
4930c46e65c7SJoe Carnuccio mcp->mb[6] = MSW(MSD(str_dma));
4931c46e65c7SJoe Carnuccio mcp->mb[7] = LSW(MSD(str_dma));
4932c46e65c7SJoe Carnuccio mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4933c46e65c7SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
4934c46e65c7SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
4935c46e65c7SJoe Carnuccio mcp->flags = 0;
4936c46e65c7SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
4937c46e65c7SJoe Carnuccio
4938c46e65c7SJoe Carnuccio if (rval != QLA_SUCCESS) {
4939c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1180,
4940c46e65c7SJoe Carnuccio "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4941c46e65c7SJoe Carnuccio } else {
4942c46e65c7SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4943c46e65c7SJoe Carnuccio "Done %s.\n", __func__);
4944c46e65c7SJoe Carnuccio }
4945c46e65c7SJoe Carnuccio
4946c46e65c7SJoe Carnuccio dma_pool_free(ha->s_dma_pool, str, str_dma);
4947c46e65c7SJoe Carnuccio
4948c46e65c7SJoe Carnuccio return rval;
4949c46e65c7SJoe Carnuccio }
4950c46e65c7SJoe Carnuccio
4951edd05de1SDuane Grigsby int
qla24xx_get_port_login_templ(scsi_qla_host_t * vha,dma_addr_t buf_dma,void * buf,uint16_t bufsiz)4952edd05de1SDuane Grigsby qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
4953edd05de1SDuane Grigsby void *buf, uint16_t bufsiz)
4954edd05de1SDuane Grigsby {
4955edd05de1SDuane Grigsby int rval, i;
4956edd05de1SDuane Grigsby mbx_cmd_t mc;
4957edd05de1SDuane Grigsby mbx_cmd_t *mcp = &mc;
4958edd05de1SDuane Grigsby uint32_t *bp;
4959edd05de1SDuane Grigsby
4960edd05de1SDuane Grigsby if (!IS_FWI2_CAPABLE(vha->hw))
4961edd05de1SDuane Grigsby return QLA_FUNCTION_FAILED;
4962edd05de1SDuane Grigsby
4963edd05de1SDuane Grigsby ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4964edd05de1SDuane Grigsby "Entered %s.\n", __func__);
4965edd05de1SDuane Grigsby
4966edd05de1SDuane Grigsby mcp->mb[0] = MBC_GET_RNID_PARAMS;
4967edd05de1SDuane Grigsby mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8;
4968edd05de1SDuane Grigsby mcp->mb[2] = MSW(buf_dma);
4969edd05de1SDuane Grigsby mcp->mb[3] = LSW(buf_dma);
4970edd05de1SDuane Grigsby mcp->mb[6] = MSW(MSD(buf_dma));
4971edd05de1SDuane Grigsby mcp->mb[7] = LSW(MSD(buf_dma));
4972edd05de1SDuane Grigsby mcp->mb[8] = bufsiz/4;
4973edd05de1SDuane Grigsby mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4974edd05de1SDuane Grigsby mcp->in_mb = MBX_1|MBX_0;
4975edd05de1SDuane Grigsby mcp->tov = MBX_TOV_SECONDS;
4976edd05de1SDuane Grigsby mcp->flags = 0;
4977edd05de1SDuane Grigsby rval = qla2x00_mailbox_command(vha, mcp);
4978edd05de1SDuane Grigsby
4979edd05de1SDuane Grigsby if (rval != QLA_SUCCESS) {
4980edd05de1SDuane Grigsby ql_dbg(ql_dbg_mbx, vha, 0x115a,
4981edd05de1SDuane Grigsby "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4982edd05de1SDuane Grigsby } else {
4983edd05de1SDuane Grigsby ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4984edd05de1SDuane Grigsby "Done %s.\n", __func__);
4985edd05de1SDuane Grigsby bp = (uint32_t *) buf;
4986edd05de1SDuane Grigsby for (i = 0; i < (bufsiz-4)/4; i++, bp++)
49877ffa5b93SBart Van Assche *bp = le32_to_cpu((__force __le32)*bp);
4988edd05de1SDuane Grigsby }
4989edd05de1SDuane Grigsby
4990edd05de1SDuane Grigsby return rval;
4991edd05de1SDuane Grigsby }
4992edd05de1SDuane Grigsby
499344d01857SQuinn Tran #define PUREX_CMD_COUNT 4
4994818c7f87SJoe Carnuccio int
qla25xx_set_els_cmds_supported(scsi_qla_host_t * vha)4995d83a80eeSJoe Carnuccio qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
4996d83a80eeSJoe Carnuccio {
4997d83a80eeSJoe Carnuccio int rval;
4998d83a80eeSJoe Carnuccio mbx_cmd_t mc;
4999d83a80eeSJoe Carnuccio mbx_cmd_t *mcp = &mc;
5000d83a80eeSJoe Carnuccio uint8_t *els_cmd_map;
500144d01857SQuinn Tran uint8_t active_cnt = 0;
5002d83a80eeSJoe Carnuccio dma_addr_t els_cmd_map_dma;
500362e9dd17SShyam Sundar uint8_t cmd_opcode[PUREX_CMD_COUNT];
500462e9dd17SShyam Sundar uint8_t i, index, purex_bit;
5005d83a80eeSJoe Carnuccio struct qla_hw_data *ha = vha->hw;
5006d83a80eeSJoe Carnuccio
500762e9dd17SShyam Sundar if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
500862e9dd17SShyam Sundar !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
5009d83a80eeSJoe Carnuccio return QLA_SUCCESS;
5010d83a80eeSJoe Carnuccio
5011d83a80eeSJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
5012d83a80eeSJoe Carnuccio "Entered %s.\n", __func__);
5013d83a80eeSJoe Carnuccio
5014d83a80eeSJoe Carnuccio els_cmd_map = dma_alloc_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE,
5015d83a80eeSJoe Carnuccio &els_cmd_map_dma, GFP_KERNEL);
5016d83a80eeSJoe Carnuccio if (!els_cmd_map) {
5017d83a80eeSJoe Carnuccio ql_log(ql_log_warn, vha, 0x7101,
5018d83a80eeSJoe Carnuccio "Failed to allocate RDP els command param.\n");
5019d83a80eeSJoe Carnuccio return QLA_MEMORY_ALLOC_FAILED;
5020d83a80eeSJoe Carnuccio }
5021d83a80eeSJoe Carnuccio
502262e9dd17SShyam Sundar /* List of Purex ELS */
502344d01857SQuinn Tran if (ql2xrdpenable) {
502444d01857SQuinn Tran cmd_opcode[active_cnt] = ELS_RDP;
502544d01857SQuinn Tran active_cnt++;
502644d01857SQuinn Tran }
502744d01857SQuinn Tran if (ha->flags.scm_supported_f) {
502844d01857SQuinn Tran cmd_opcode[active_cnt] = ELS_FPIN;
502944d01857SQuinn Tran active_cnt++;
503044d01857SQuinn Tran }
503144d01857SQuinn Tran if (ha->flags.edif_enabled) {
503244d01857SQuinn Tran cmd_opcode[active_cnt] = ELS_AUTH_ELS;
503344d01857SQuinn Tran active_cnt++;
503444d01857SQuinn Tran }
503562e9dd17SShyam Sundar
503644d01857SQuinn Tran for (i = 0; i < active_cnt; i++) {
503762e9dd17SShyam Sundar index = cmd_opcode[i] / 8;
503862e9dd17SShyam Sundar purex_bit = cmd_opcode[i] % 8;
503962e9dd17SShyam Sundar els_cmd_map[index] |= 1 << purex_bit;
504062e9dd17SShyam Sundar }
5041d83a80eeSJoe Carnuccio
5042d83a80eeSJoe Carnuccio mcp->mb[0] = MBC_SET_RNID_PARAMS;
5043d83a80eeSJoe Carnuccio mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
5044d83a80eeSJoe Carnuccio mcp->mb[2] = MSW(LSD(els_cmd_map_dma));
5045d83a80eeSJoe Carnuccio mcp->mb[3] = LSW(LSD(els_cmd_map_dma));
5046d83a80eeSJoe Carnuccio mcp->mb[6] = MSW(MSD(els_cmd_map_dma));
5047d83a80eeSJoe Carnuccio mcp->mb[7] = LSW(MSD(els_cmd_map_dma));
5048d83a80eeSJoe Carnuccio mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
5049d83a80eeSJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
5050d83a80eeSJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
5051d83a80eeSJoe Carnuccio mcp->flags = MBX_DMA_OUT;
5052d83a80eeSJoe Carnuccio mcp->buf_size = ELS_CMD_MAP_SIZE;
5053d83a80eeSJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
5054d83a80eeSJoe Carnuccio
5055d83a80eeSJoe Carnuccio if (rval != QLA_SUCCESS) {
5056d83a80eeSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x118d,
5057d83a80eeSJoe Carnuccio "Failed=%x (%x,%x).\n", rval, mcp->mb[0], mcp->mb[1]);
5058d83a80eeSJoe Carnuccio } else {
5059d83a80eeSJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
5060d83a80eeSJoe Carnuccio "Done %s.\n", __func__);
5061d83a80eeSJoe Carnuccio }
5062d83a80eeSJoe Carnuccio
5063650b323cSChristophe JAILLET dma_free_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE,
5064d83a80eeSJoe Carnuccio els_cmd_map, els_cmd_map_dma);
5065d83a80eeSJoe Carnuccio
5066d83a80eeSJoe Carnuccio return rval;
5067d83a80eeSJoe Carnuccio }
5068d83a80eeSJoe Carnuccio
5069fe52f6e1SJoe Carnuccio static int
qla2x00_read_asic_temperature(scsi_qla_host_t * vha,uint16_t * temp)5070fe52f6e1SJoe Carnuccio qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
5071fe52f6e1SJoe Carnuccio {
5072fe52f6e1SJoe Carnuccio int rval;
5073fe52f6e1SJoe Carnuccio mbx_cmd_t mc;
5074fe52f6e1SJoe Carnuccio mbx_cmd_t *mcp = &mc;
5075fe52f6e1SJoe Carnuccio
5076fe52f6e1SJoe Carnuccio if (!IS_FWI2_CAPABLE(vha->hw))
5077fe52f6e1SJoe Carnuccio return QLA_FUNCTION_FAILED;
5078fe52f6e1SJoe Carnuccio
5079fe52f6e1SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
5080fe52f6e1SJoe Carnuccio "Entered %s.\n", __func__);
5081fe52f6e1SJoe Carnuccio
5082fe52f6e1SJoe Carnuccio mcp->mb[0] = MBC_GET_RNID_PARAMS;
5083fe52f6e1SJoe Carnuccio mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
5084fe52f6e1SJoe Carnuccio mcp->out_mb = MBX_1|MBX_0;
5085fe52f6e1SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
5086fe52f6e1SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
5087fe52f6e1SJoe Carnuccio mcp->flags = 0;
5088fe52f6e1SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
5089fe52f6e1SJoe Carnuccio *temp = mcp->mb[1];
5090fe52f6e1SJoe Carnuccio
5091fe52f6e1SJoe Carnuccio if (rval != QLA_SUCCESS) {
5092fe52f6e1SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x115a,
5093fe52f6e1SJoe Carnuccio "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
5094fe52f6e1SJoe Carnuccio } else {
5095fe52f6e1SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
5096fe52f6e1SJoe Carnuccio "Done %s.\n", __func__);
5097fe52f6e1SJoe Carnuccio }
5098fe52f6e1SJoe Carnuccio
5099fe52f6e1SJoe Carnuccio return rval;
5100fe52f6e1SJoe Carnuccio }
5101fe52f6e1SJoe Carnuccio
51023a11711aSJoe Carnuccio int
qla2x00_read_sfp(scsi_qla_host_t * vha,dma_addr_t sfp_dma,uint8_t * sfp,uint16_t dev,uint16_t off,uint16_t len,uint16_t opt)51036766df9eSJoe Carnuccio qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
51046766df9eSJoe Carnuccio uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
5105ad0ecd61SJoe Carnuccio {
5106ad0ecd61SJoe Carnuccio int rval;
5107ad0ecd61SJoe Carnuccio mbx_cmd_t mc;
5108ad0ecd61SJoe Carnuccio mbx_cmd_t *mcp = &mc;
51096766df9eSJoe Carnuccio struct qla_hw_data *ha = vha->hw;
51106766df9eSJoe Carnuccio
51115f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
51125f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
51137c3df132SSaurav Kashyap
51146766df9eSJoe Carnuccio if (!IS_FWI2_CAPABLE(ha))
51156766df9eSJoe Carnuccio return QLA_FUNCTION_FAILED;
5116ad0ecd61SJoe Carnuccio
51176766df9eSJoe Carnuccio if (len == 1)
51186766df9eSJoe Carnuccio opt |= BIT_0;
51196766df9eSJoe Carnuccio
5120ad0ecd61SJoe Carnuccio mcp->mb[0] = MBC_READ_SFP;
5121ad0ecd61SJoe Carnuccio mcp->mb[1] = dev;
5122818c7f87SJoe Carnuccio mcp->mb[2] = MSW(LSD(sfp_dma));
5123818c7f87SJoe Carnuccio mcp->mb[3] = LSW(LSD(sfp_dma));
5124ad0ecd61SJoe Carnuccio mcp->mb[6] = MSW(MSD(sfp_dma));
5125ad0ecd61SJoe Carnuccio mcp->mb[7] = LSW(MSD(sfp_dma));
5126ad0ecd61SJoe Carnuccio mcp->mb[8] = len;
51276766df9eSJoe Carnuccio mcp->mb[9] = off;
5128ad0ecd61SJoe Carnuccio mcp->mb[10] = opt;
5129ad0ecd61SJoe Carnuccio mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
51301bff6cc8SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
5131ad0ecd61SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
5132ad0ecd61SJoe Carnuccio mcp->flags = 0;
5133ad0ecd61SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
5134ad0ecd61SJoe Carnuccio
5135ad0ecd61SJoe Carnuccio if (opt & BIT_0)
51361bff6cc8SJoe Carnuccio *sfp = mcp->mb[1];
5137ad0ecd61SJoe Carnuccio
5138ad0ecd61SJoe Carnuccio if (rval != QLA_SUCCESS) {
51397c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10e9,
51407c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
51412a3192a3SJoe Carnuccio if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) {
5142e4e3a2ceSQuinn Tran /* sfp is not there */
5143e4e3a2ceSQuinn Tran rval = QLA_INTERFACE_ERROR;
51442a3192a3SJoe Carnuccio }
5145ad0ecd61SJoe Carnuccio } else {
51465f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
51475f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
5148ad0ecd61SJoe Carnuccio }
5149ad0ecd61SJoe Carnuccio
5150ad0ecd61SJoe Carnuccio return rval;
5151ad0ecd61SJoe Carnuccio }
5152ad0ecd61SJoe Carnuccio
5153ad0ecd61SJoe Carnuccio int
qla2x00_write_sfp(scsi_qla_host_t * vha,dma_addr_t sfp_dma,uint8_t * sfp,uint16_t dev,uint16_t off,uint16_t len,uint16_t opt)51546766df9eSJoe Carnuccio qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
51556766df9eSJoe Carnuccio uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
5156ad0ecd61SJoe Carnuccio {
5157ad0ecd61SJoe Carnuccio int rval;
5158ad0ecd61SJoe Carnuccio mbx_cmd_t mc;
5159ad0ecd61SJoe Carnuccio mbx_cmd_t *mcp = &mc;
51606766df9eSJoe Carnuccio struct qla_hw_data *ha = vha->hw;
51616766df9eSJoe Carnuccio
51625f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
51635f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
51647c3df132SSaurav Kashyap
51656766df9eSJoe Carnuccio if (!IS_FWI2_CAPABLE(ha))
51666766df9eSJoe Carnuccio return QLA_FUNCTION_FAILED;
5167ad0ecd61SJoe Carnuccio
51686766df9eSJoe Carnuccio if (len == 1)
51696766df9eSJoe Carnuccio opt |= BIT_0;
51706766df9eSJoe Carnuccio
5171ad0ecd61SJoe Carnuccio if (opt & BIT_0)
5172ad0ecd61SJoe Carnuccio len = *sfp;
5173ad0ecd61SJoe Carnuccio
5174ad0ecd61SJoe Carnuccio mcp->mb[0] = MBC_WRITE_SFP;
5175ad0ecd61SJoe Carnuccio mcp->mb[1] = dev;
5176818c7f87SJoe Carnuccio mcp->mb[2] = MSW(LSD(sfp_dma));
5177818c7f87SJoe Carnuccio mcp->mb[3] = LSW(LSD(sfp_dma));
5178ad0ecd61SJoe Carnuccio mcp->mb[6] = MSW(MSD(sfp_dma));
5179ad0ecd61SJoe Carnuccio mcp->mb[7] = LSW(MSD(sfp_dma));
5180ad0ecd61SJoe Carnuccio mcp->mb[8] = len;
51816766df9eSJoe Carnuccio mcp->mb[9] = off;
5182ad0ecd61SJoe Carnuccio mcp->mb[10] = opt;
5183ad0ecd61SJoe Carnuccio mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
51846766df9eSJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
5185ad0ecd61SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
5186ad0ecd61SJoe Carnuccio mcp->flags = 0;
5187ad0ecd61SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
5188ad0ecd61SJoe Carnuccio
5189ad0ecd61SJoe Carnuccio if (rval != QLA_SUCCESS) {
51907c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10ec,
51917c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5192ad0ecd61SJoe Carnuccio } else {
51935f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
51945f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
5195ad0ecd61SJoe Carnuccio }
5196ad0ecd61SJoe Carnuccio
5197ad0ecd61SJoe Carnuccio return rval;
5198ad0ecd61SJoe Carnuccio }
5199ce0423f4SAndrew Vasquez
5200ce0423f4SAndrew Vasquez int
qla2x00_get_xgmac_stats(scsi_qla_host_t * vha,dma_addr_t stats_dma,uint16_t size_in_bytes,uint16_t * actual_size)5201ce0423f4SAndrew Vasquez qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
5202ce0423f4SAndrew Vasquez uint16_t size_in_bytes, uint16_t *actual_size)
5203ce0423f4SAndrew Vasquez {
5204ce0423f4SAndrew Vasquez int rval;
5205ce0423f4SAndrew Vasquez mbx_cmd_t mc;
5206ce0423f4SAndrew Vasquez mbx_cmd_t *mcp = &mc;
5207ce0423f4SAndrew Vasquez
52085f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
52095f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
52107c3df132SSaurav Kashyap
52116246b8a1SGiridhar Malavali if (!IS_CNA_CAPABLE(vha->hw))
5212ce0423f4SAndrew Vasquez return QLA_FUNCTION_FAILED;
5213ce0423f4SAndrew Vasquez
5214ce0423f4SAndrew Vasquez mcp->mb[0] = MBC_GET_XGMAC_STATS;
5215ce0423f4SAndrew Vasquez mcp->mb[2] = MSW(stats_dma);
5216ce0423f4SAndrew Vasquez mcp->mb[3] = LSW(stats_dma);
5217ce0423f4SAndrew Vasquez mcp->mb[6] = MSW(MSD(stats_dma));
5218ce0423f4SAndrew Vasquez mcp->mb[7] = LSW(MSD(stats_dma));
5219ce0423f4SAndrew Vasquez mcp->mb[8] = size_in_bytes >> 2;
5220ce0423f4SAndrew Vasquez mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
5221ce0423f4SAndrew Vasquez mcp->in_mb = MBX_2|MBX_1|MBX_0;
5222ce0423f4SAndrew Vasquez mcp->tov = MBX_TOV_SECONDS;
5223ce0423f4SAndrew Vasquez mcp->flags = 0;
5224ce0423f4SAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
5225ce0423f4SAndrew Vasquez
5226ce0423f4SAndrew Vasquez if (rval != QLA_SUCCESS) {
52277c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10ef,
52287c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
52297c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
5230ce0423f4SAndrew Vasquez } else {
52315f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
52325f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
52337c3df132SSaurav Kashyap
5234ce0423f4SAndrew Vasquez
5235ce0423f4SAndrew Vasquez *actual_size = mcp->mb[2] << 2;
5236ce0423f4SAndrew Vasquez }
5237ce0423f4SAndrew Vasquez
5238ce0423f4SAndrew Vasquez return rval;
5239ce0423f4SAndrew Vasquez }
524011bbc1d8SAndrew Vasquez
524111bbc1d8SAndrew Vasquez int
qla2x00_get_dcbx_params(scsi_qla_host_t * vha,dma_addr_t tlv_dma,uint16_t size)524211bbc1d8SAndrew Vasquez qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
524311bbc1d8SAndrew Vasquez uint16_t size)
524411bbc1d8SAndrew Vasquez {
524511bbc1d8SAndrew Vasquez int rval;
524611bbc1d8SAndrew Vasquez mbx_cmd_t mc;
524711bbc1d8SAndrew Vasquez mbx_cmd_t *mcp = &mc;
524811bbc1d8SAndrew Vasquez
52495f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
52505f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
52517c3df132SSaurav Kashyap
52526246b8a1SGiridhar Malavali if (!IS_CNA_CAPABLE(vha->hw))
525311bbc1d8SAndrew Vasquez return QLA_FUNCTION_FAILED;
525411bbc1d8SAndrew Vasquez
525511bbc1d8SAndrew Vasquez mcp->mb[0] = MBC_GET_DCBX_PARAMS;
525611bbc1d8SAndrew Vasquez mcp->mb[1] = 0;
525711bbc1d8SAndrew Vasquez mcp->mb[2] = MSW(tlv_dma);
525811bbc1d8SAndrew Vasquez mcp->mb[3] = LSW(tlv_dma);
525911bbc1d8SAndrew Vasquez mcp->mb[6] = MSW(MSD(tlv_dma));
526011bbc1d8SAndrew Vasquez mcp->mb[7] = LSW(MSD(tlv_dma));
526111bbc1d8SAndrew Vasquez mcp->mb[8] = size;
526211bbc1d8SAndrew Vasquez mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
526311bbc1d8SAndrew Vasquez mcp->in_mb = MBX_2|MBX_1|MBX_0;
526411bbc1d8SAndrew Vasquez mcp->tov = MBX_TOV_SECONDS;
526511bbc1d8SAndrew Vasquez mcp->flags = 0;
526611bbc1d8SAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
526711bbc1d8SAndrew Vasquez
526811bbc1d8SAndrew Vasquez if (rval != QLA_SUCCESS) {
52697c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10f2,
52707c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
52717c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
527211bbc1d8SAndrew Vasquez } else {
52735f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
52745f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
527511bbc1d8SAndrew Vasquez }
527611bbc1d8SAndrew Vasquez
527711bbc1d8SAndrew Vasquez return rval;
527811bbc1d8SAndrew Vasquez }
527918e7555aSAndrew Vasquez
528018e7555aSAndrew Vasquez int
qla2x00_read_ram_word(scsi_qla_host_t * vha,uint32_t risc_addr,uint32_t * data)528118e7555aSAndrew Vasquez qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
528218e7555aSAndrew Vasquez {
528318e7555aSAndrew Vasquez int rval;
528418e7555aSAndrew Vasquez mbx_cmd_t mc;
528518e7555aSAndrew Vasquez mbx_cmd_t *mcp = &mc;
528618e7555aSAndrew Vasquez
52875f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
52885f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
52897c3df132SSaurav Kashyap
529018e7555aSAndrew Vasquez if (!IS_FWI2_CAPABLE(vha->hw))
529118e7555aSAndrew Vasquez return QLA_FUNCTION_FAILED;
529218e7555aSAndrew Vasquez
529318e7555aSAndrew Vasquez mcp->mb[0] = MBC_READ_RAM_EXTENDED;
529418e7555aSAndrew Vasquez mcp->mb[1] = LSW(risc_addr);
529518e7555aSAndrew Vasquez mcp->mb[8] = MSW(risc_addr);
529618e7555aSAndrew Vasquez mcp->out_mb = MBX_8|MBX_1|MBX_0;
529718e7555aSAndrew Vasquez mcp->in_mb = MBX_3|MBX_2|MBX_0;
5298c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
529918e7555aSAndrew Vasquez mcp->flags = 0;
530018e7555aSAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
530118e7555aSAndrew Vasquez if (rval != QLA_SUCCESS) {
53027c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10f5,
53037c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
530418e7555aSAndrew Vasquez } else {
53055f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
53065f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
530718e7555aSAndrew Vasquez *data = mcp->mb[3] << 16 | mcp->mb[2];
530818e7555aSAndrew Vasquez }
530918e7555aSAndrew Vasquez
531018e7555aSAndrew Vasquez return rval;
531118e7555aSAndrew Vasquez }
531218e7555aSAndrew Vasquez
531318e7555aSAndrew Vasquez int
qla2x00_loopback_test(scsi_qla_host_t * vha,struct msg_echo_lb * mreq,uint16_t * mresp)5314a9083016SGiridhar Malavali qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
5315a9083016SGiridhar Malavali uint16_t *mresp)
53169a069e19SGiridhar Malavali {
53179a069e19SGiridhar Malavali int rval;
53189a069e19SGiridhar Malavali mbx_cmd_t mc;
53199a069e19SGiridhar Malavali mbx_cmd_t *mcp = &mc;
53209a069e19SGiridhar Malavali
53215f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
53225f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
53239a069e19SGiridhar Malavali
53249a069e19SGiridhar Malavali memset(mcp->mb, 0 , sizeof(mcp->mb));
53259a069e19SGiridhar Malavali mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
53269a069e19SGiridhar Malavali mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
53279a069e19SGiridhar Malavali
53289a069e19SGiridhar Malavali /* transfer count */
53299a069e19SGiridhar Malavali mcp->mb[10] = LSW(mreq->transfer_size);
53309a069e19SGiridhar Malavali mcp->mb[11] = MSW(mreq->transfer_size);
53319a069e19SGiridhar Malavali
53329a069e19SGiridhar Malavali /* send data address */
53339a069e19SGiridhar Malavali mcp->mb[14] = LSW(mreq->send_dma);
53349a069e19SGiridhar Malavali mcp->mb[15] = MSW(mreq->send_dma);
53359a069e19SGiridhar Malavali mcp->mb[20] = LSW(MSD(mreq->send_dma));
53369a069e19SGiridhar Malavali mcp->mb[21] = MSW(MSD(mreq->send_dma));
53379a069e19SGiridhar Malavali
533825985edcSLucas De Marchi /* receive data address */
53399a069e19SGiridhar Malavali mcp->mb[16] = LSW(mreq->rcv_dma);
53409a069e19SGiridhar Malavali mcp->mb[17] = MSW(mreq->rcv_dma);
53419a069e19SGiridhar Malavali mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
53429a069e19SGiridhar Malavali mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
53439a069e19SGiridhar Malavali
53449a069e19SGiridhar Malavali /* Iteration count */
53451b98b421SJoe Carnuccio mcp->mb[18] = LSW(mreq->iteration_count);
53461b98b421SJoe Carnuccio mcp->mb[19] = MSW(mreq->iteration_count);
53479a069e19SGiridhar Malavali
53489a069e19SGiridhar Malavali mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
53499a069e19SGiridhar Malavali MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
53506246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(vha->hw))
53519a069e19SGiridhar Malavali mcp->out_mb |= MBX_2;
53529a069e19SGiridhar Malavali mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
53539a069e19SGiridhar Malavali
53549a069e19SGiridhar Malavali mcp->buf_size = mreq->transfer_size;
53559a069e19SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
53569a069e19SGiridhar Malavali mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
53579a069e19SGiridhar Malavali
53589a069e19SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
53599a069e19SGiridhar Malavali
53609a069e19SGiridhar Malavali if (rval != QLA_SUCCESS) {
53617c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10f8,
53627c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
53637c3df132SSaurav Kashyap "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
53647c3df132SSaurav Kashyap mcp->mb[3], mcp->mb[18], mcp->mb[19]);
53659a069e19SGiridhar Malavali } else {
53665f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
53675f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
53689a069e19SGiridhar Malavali }
53699a069e19SGiridhar Malavali
53709a069e19SGiridhar Malavali /* Copy mailbox information */
53719a069e19SGiridhar Malavali memcpy( mresp, mcp->mb, 64);
53729a069e19SGiridhar Malavali return rval;
53739a069e19SGiridhar Malavali }
53749a069e19SGiridhar Malavali
53759a069e19SGiridhar Malavali int
qla2x00_echo_test(scsi_qla_host_t * vha,struct msg_echo_lb * mreq,uint16_t * mresp)5376a9083016SGiridhar Malavali qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
5377a9083016SGiridhar Malavali uint16_t *mresp)
53789a069e19SGiridhar Malavali {
53799a069e19SGiridhar Malavali int rval;
53809a069e19SGiridhar Malavali mbx_cmd_t mc;
53819a069e19SGiridhar Malavali mbx_cmd_t *mcp = &mc;
53829a069e19SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
53839a069e19SGiridhar Malavali
53845f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
53855f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
53869a069e19SGiridhar Malavali
53879a069e19SGiridhar Malavali memset(mcp->mb, 0 , sizeof(mcp->mb));
53889a069e19SGiridhar Malavali mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
53891d634965SJoe Carnuccio /* BIT_6 specifies 64bit address */
53901d634965SJoe Carnuccio mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
53916246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(ha)) {
5392a9083016SGiridhar Malavali mcp->mb[2] = vha->fcoe_fcf_idx;
5393a9083016SGiridhar Malavali }
53949a069e19SGiridhar Malavali mcp->mb[16] = LSW(mreq->rcv_dma);
53959a069e19SGiridhar Malavali mcp->mb[17] = MSW(mreq->rcv_dma);
53969a069e19SGiridhar Malavali mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
53979a069e19SGiridhar Malavali mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
53989a069e19SGiridhar Malavali
53999a069e19SGiridhar Malavali mcp->mb[10] = LSW(mreq->transfer_size);
54009a069e19SGiridhar Malavali
54019a069e19SGiridhar Malavali mcp->mb[14] = LSW(mreq->send_dma);
54029a069e19SGiridhar Malavali mcp->mb[15] = MSW(mreq->send_dma);
54039a069e19SGiridhar Malavali mcp->mb[20] = LSW(MSD(mreq->send_dma));
54049a069e19SGiridhar Malavali mcp->mb[21] = MSW(MSD(mreq->send_dma));
54059a069e19SGiridhar Malavali
54069a069e19SGiridhar Malavali mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
54079a069e19SGiridhar Malavali MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
54086246b8a1SGiridhar Malavali if (IS_CNA_CAPABLE(ha))
54099a069e19SGiridhar Malavali mcp->out_mb |= MBX_2;
54109a069e19SGiridhar Malavali
54119a069e19SGiridhar Malavali mcp->in_mb = MBX_0;
541283cfd3dcSJoe Carnuccio if (IS_CNA_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
541383cfd3dcSJoe Carnuccio IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
54149a069e19SGiridhar Malavali mcp->in_mb |= MBX_1;
541583cfd3dcSJoe Carnuccio if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
541683cfd3dcSJoe Carnuccio IS_QLA28XX(ha))
54179a069e19SGiridhar Malavali mcp->in_mb |= MBX_3;
54189a069e19SGiridhar Malavali
54199a069e19SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
54209a069e19SGiridhar Malavali mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
54219a069e19SGiridhar Malavali mcp->buf_size = mreq->transfer_size;
54229a069e19SGiridhar Malavali
54239a069e19SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
54249a069e19SGiridhar Malavali
54259a069e19SGiridhar Malavali if (rval != QLA_SUCCESS) {
54267c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10fb,
54277c3df132SSaurav Kashyap "Failed=%x mb[0]=%x mb[1]=%x.\n",
54287c3df132SSaurav Kashyap rval, mcp->mb[0], mcp->mb[1]);
54299a069e19SGiridhar Malavali } else {
54305f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
54315f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
54329a069e19SGiridhar Malavali }
54339a069e19SGiridhar Malavali
54349a069e19SGiridhar Malavali /* Copy mailbox information */
54356dbdda4dSGiridhar Malavali memcpy(mresp, mcp->mb, 64);
54369a069e19SGiridhar Malavali return rval;
54379a069e19SGiridhar Malavali }
54386dbdda4dSGiridhar Malavali
54399a069e19SGiridhar Malavali int
qla84xx_reset_chip(scsi_qla_host_t * vha,uint16_t enable_diagnostic)54407c3df132SSaurav Kashyap qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
54419a069e19SGiridhar Malavali {
54429a069e19SGiridhar Malavali int rval;
54439a069e19SGiridhar Malavali mbx_cmd_t mc;
54449a069e19SGiridhar Malavali mbx_cmd_t *mcp = &mc;
54459a069e19SGiridhar Malavali
54465f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
54477c3df132SSaurav Kashyap "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
54489a069e19SGiridhar Malavali
54499a069e19SGiridhar Malavali mcp->mb[0] = MBC_ISP84XX_RESET;
54509a069e19SGiridhar Malavali mcp->mb[1] = enable_diagnostic;
54519a069e19SGiridhar Malavali mcp->out_mb = MBX_1|MBX_0;
54529a069e19SGiridhar Malavali mcp->in_mb = MBX_1|MBX_0;
54539a069e19SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
54549a069e19SGiridhar Malavali mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
54557c3df132SSaurav Kashyap rval = qla2x00_mailbox_command(vha, mcp);
54569a069e19SGiridhar Malavali
54579a069e19SGiridhar Malavali if (rval != QLA_SUCCESS)
54587c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
54599a069e19SGiridhar Malavali else
54605f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
54615f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
54629a069e19SGiridhar Malavali
54639a069e19SGiridhar Malavali return rval;
54649a069e19SGiridhar Malavali }
54659a069e19SGiridhar Malavali
54669a069e19SGiridhar Malavali int
qla2x00_write_ram_word(scsi_qla_host_t * vha,uint32_t risc_addr,uint32_t data)546718e7555aSAndrew Vasquez qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
546818e7555aSAndrew Vasquez {
546918e7555aSAndrew Vasquez int rval;
547018e7555aSAndrew Vasquez mbx_cmd_t mc;
547118e7555aSAndrew Vasquez mbx_cmd_t *mcp = &mc;
547218e7555aSAndrew Vasquez
54735f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
54745f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
54757c3df132SSaurav Kashyap
547618e7555aSAndrew Vasquez if (!IS_FWI2_CAPABLE(vha->hw))
547718e7555aSAndrew Vasquez return QLA_FUNCTION_FAILED;
547818e7555aSAndrew Vasquez
547918e7555aSAndrew Vasquez mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
548018e7555aSAndrew Vasquez mcp->mb[1] = LSW(risc_addr);
548118e7555aSAndrew Vasquez mcp->mb[2] = LSW(data);
548218e7555aSAndrew Vasquez mcp->mb[3] = MSW(data);
548318e7555aSAndrew Vasquez mcp->mb[8] = MSW(risc_addr);
548418e7555aSAndrew Vasquez mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
54852a3192a3SJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
5486c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
548718e7555aSAndrew Vasquez mcp->flags = 0;
548818e7555aSAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
548918e7555aSAndrew Vasquez if (rval != QLA_SUCCESS) {
54907c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1101,
54912a3192a3SJoe Carnuccio "Failed=%x mb[0]=%x mb[1]=%x.\n",
54922a3192a3SJoe Carnuccio rval, mcp->mb[0], mcp->mb[1]);
549318e7555aSAndrew Vasquez } else {
54945f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
54955f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
549618e7555aSAndrew Vasquez }
549718e7555aSAndrew Vasquez
549818e7555aSAndrew Vasquez return rval;
549918e7555aSAndrew Vasquez }
55003064ff39SMichael Hernandez
55013064ff39SMichael Hernandez int
qla81xx_write_mpi_register(scsi_qla_host_t * vha,uint16_t * mb)5502b1d46989SMadhuranath Iyengar qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
5503b1d46989SMadhuranath Iyengar {
5504b1d46989SMadhuranath Iyengar int rval;
5505b1d46989SMadhuranath Iyengar uint32_t stat, timer;
5506b1d46989SMadhuranath Iyengar uint16_t mb0 = 0;
5507b1d46989SMadhuranath Iyengar struct qla_hw_data *ha = vha->hw;
5508b1d46989SMadhuranath Iyengar struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
5509b1d46989SMadhuranath Iyengar
5510b1d46989SMadhuranath Iyengar rval = QLA_SUCCESS;
5511b1d46989SMadhuranath Iyengar
55125f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
55135f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
5514b1d46989SMadhuranath Iyengar
5515b1d46989SMadhuranath Iyengar clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
5516b1d46989SMadhuranath Iyengar
5517b1d46989SMadhuranath Iyengar /* Write the MBC data to the registers */
551804474d3aSBart Van Assche wrt_reg_word(®->mailbox0, MBC_WRITE_MPI_REGISTER);
551904474d3aSBart Van Assche wrt_reg_word(®->mailbox1, mb[0]);
552004474d3aSBart Van Assche wrt_reg_word(®->mailbox2, mb[1]);
552104474d3aSBart Van Assche wrt_reg_word(®->mailbox3, mb[2]);
552204474d3aSBart Van Assche wrt_reg_word(®->mailbox4, mb[3]);
5523b1d46989SMadhuranath Iyengar
552404474d3aSBart Van Assche wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT);
5525b1d46989SMadhuranath Iyengar
5526b1d46989SMadhuranath Iyengar /* Poll for MBC interrupt */
5527b1d46989SMadhuranath Iyengar for (timer = 6000000; timer; timer--) {
5528b1d46989SMadhuranath Iyengar /* Check for pending interrupts. */
552904474d3aSBart Van Assche stat = rd_reg_dword(®->host_status);
5530b1d46989SMadhuranath Iyengar if (stat & HSRX_RISC_INT) {
5531b1d46989SMadhuranath Iyengar stat &= 0xff;
5532b1d46989SMadhuranath Iyengar
5533b1d46989SMadhuranath Iyengar if (stat == 0x1 || stat == 0x2 ||
5534b1d46989SMadhuranath Iyengar stat == 0x10 || stat == 0x11) {
5535b1d46989SMadhuranath Iyengar set_bit(MBX_INTERRUPT,
5536b1d46989SMadhuranath Iyengar &ha->mbx_cmd_flags);
553704474d3aSBart Van Assche mb0 = rd_reg_word(®->mailbox0);
553804474d3aSBart Van Assche wrt_reg_dword(®->hccr,
5539b1d46989SMadhuranath Iyengar HCCRX_CLR_RISC_INT);
554004474d3aSBart Van Assche rd_reg_dword(®->hccr);
5541b1d46989SMadhuranath Iyengar break;
5542b1d46989SMadhuranath Iyengar }
5543b1d46989SMadhuranath Iyengar }
5544b1d46989SMadhuranath Iyengar udelay(5);
5545b1d46989SMadhuranath Iyengar }
5546b1d46989SMadhuranath Iyengar
5547b1d46989SMadhuranath Iyengar if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
5548b1d46989SMadhuranath Iyengar rval = mb0 & MBS_MASK;
5549b1d46989SMadhuranath Iyengar else
5550b1d46989SMadhuranath Iyengar rval = QLA_FUNCTION_FAILED;
5551b1d46989SMadhuranath Iyengar
5552b1d46989SMadhuranath Iyengar if (rval != QLA_SUCCESS) {
55537c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1104,
55547c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mb[0]);
5555b1d46989SMadhuranath Iyengar } else {
55565f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
55575f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
5558b1d46989SMadhuranath Iyengar }
5559b1d46989SMadhuranath Iyengar
5560b1d46989SMadhuranath Iyengar return rval;
5561b1d46989SMadhuranath Iyengar }
55626246b8a1SGiridhar Malavali
55634910b524SAnil Gurumurthy /* Set the specified data rate */
55644910b524SAnil Gurumurthy int
qla2x00_set_data_rate(scsi_qla_host_t * vha,uint16_t mode)55654910b524SAnil Gurumurthy qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode)
55664910b524SAnil Gurumurthy {
55674910b524SAnil Gurumurthy int rval;
55684910b524SAnil Gurumurthy mbx_cmd_t mc;
55694910b524SAnil Gurumurthy mbx_cmd_t *mcp = &mc;
55704910b524SAnil Gurumurthy struct qla_hw_data *ha = vha->hw;
55714910b524SAnil Gurumurthy uint16_t val;
55724910b524SAnil Gurumurthy
55734910b524SAnil Gurumurthy ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
55744910b524SAnil Gurumurthy "Entered %s speed:0x%x mode:0x%x.\n", __func__, ha->set_data_rate,
55754910b524SAnil Gurumurthy mode);
55764910b524SAnil Gurumurthy
55774910b524SAnil Gurumurthy if (!IS_FWI2_CAPABLE(ha))
55784910b524SAnil Gurumurthy return QLA_FUNCTION_FAILED;
55794910b524SAnil Gurumurthy
55804910b524SAnil Gurumurthy memset(mcp, 0, sizeof(*mcp));
55814910b524SAnil Gurumurthy switch (ha->set_data_rate) {
55824910b524SAnil Gurumurthy case PORT_SPEED_AUTO:
55834910b524SAnil Gurumurthy case PORT_SPEED_4GB:
55844910b524SAnil Gurumurthy case PORT_SPEED_8GB:
55854910b524SAnil Gurumurthy case PORT_SPEED_16GB:
55864910b524SAnil Gurumurthy case PORT_SPEED_32GB:
55874910b524SAnil Gurumurthy val = ha->set_data_rate;
55884910b524SAnil Gurumurthy break;
55894910b524SAnil Gurumurthy default:
55904910b524SAnil Gurumurthy ql_log(ql_log_warn, vha, 0x1199,
55914910b524SAnil Gurumurthy "Unrecognized speed setting:%d. Setting Autoneg\n",
55924910b524SAnil Gurumurthy ha->set_data_rate);
55934910b524SAnil Gurumurthy val = ha->set_data_rate = PORT_SPEED_AUTO;
55944910b524SAnil Gurumurthy break;
55954910b524SAnil Gurumurthy }
55964910b524SAnil Gurumurthy
55974910b524SAnil Gurumurthy mcp->mb[0] = MBC_DATA_RATE;
55984910b524SAnil Gurumurthy mcp->mb[1] = mode;
55994910b524SAnil Gurumurthy mcp->mb[2] = val;
56004910b524SAnil Gurumurthy
56014910b524SAnil Gurumurthy mcp->out_mb = MBX_2|MBX_1|MBX_0;
56024910b524SAnil Gurumurthy mcp->in_mb = MBX_2|MBX_1|MBX_0;
5603ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
56044910b524SAnil Gurumurthy mcp->in_mb |= MBX_4|MBX_3;
56054910b524SAnil Gurumurthy mcp->tov = MBX_TOV_SECONDS;
56064910b524SAnil Gurumurthy mcp->flags = 0;
56074910b524SAnil Gurumurthy rval = qla2x00_mailbox_command(vha, mcp);
56084910b524SAnil Gurumurthy if (rval != QLA_SUCCESS) {
56094910b524SAnil Gurumurthy ql_dbg(ql_dbg_mbx, vha, 0x1107,
56104910b524SAnil Gurumurthy "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
56114910b524SAnil Gurumurthy } else {
56124910b524SAnil Gurumurthy if (mcp->mb[1] != 0x7)
56134910b524SAnil Gurumurthy ql_dbg(ql_dbg_mbx, vha, 0x1179,
56144910b524SAnil Gurumurthy "Speed set:0x%x\n", mcp->mb[1]);
56154910b524SAnil Gurumurthy
56164910b524SAnil Gurumurthy ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
56174910b524SAnil Gurumurthy "Done %s.\n", __func__);
56184910b524SAnil Gurumurthy }
56194910b524SAnil Gurumurthy
56204910b524SAnil Gurumurthy return rval;
56214910b524SAnil Gurumurthy }
56224910b524SAnil Gurumurthy
5623b1d46989SMadhuranath Iyengar int
qla2x00_get_data_rate(scsi_qla_host_t * vha)56243064ff39SMichael Hernandez qla2x00_get_data_rate(scsi_qla_host_t *vha)
56253064ff39SMichael Hernandez {
56263064ff39SMichael Hernandez int rval;
56273064ff39SMichael Hernandez mbx_cmd_t mc;
56283064ff39SMichael Hernandez mbx_cmd_t *mcp = &mc;
56293064ff39SMichael Hernandez struct qla_hw_data *ha = vha->hw;
56303064ff39SMichael Hernandez
56315f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
56325f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
56337c3df132SSaurav Kashyap
56343064ff39SMichael Hernandez if (!IS_FWI2_CAPABLE(ha))
56353064ff39SMichael Hernandez return QLA_FUNCTION_FAILED;
56363064ff39SMichael Hernandez
56373064ff39SMichael Hernandez mcp->mb[0] = MBC_DATA_RATE;
56384910b524SAnil Gurumurthy mcp->mb[1] = QLA_GET_DATA_RATE;
56393064ff39SMichael Hernandez mcp->out_mb = MBX_1|MBX_0;
56403064ff39SMichael Hernandez mcp->in_mb = MBX_2|MBX_1|MBX_0;
5641ecc89f25SJoe Carnuccio if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
56420d6a536cSJoe Carnuccio mcp->in_mb |= MBX_4|MBX_3;
56433064ff39SMichael Hernandez mcp->tov = MBX_TOV_SECONDS;
56443064ff39SMichael Hernandez mcp->flags = 0;
56453064ff39SMichael Hernandez rval = qla2x00_mailbox_command(vha, mcp);
56463064ff39SMichael Hernandez if (rval != QLA_SUCCESS) {
56477c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1107,
56487c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
56493064ff39SMichael Hernandez } else {
565075666f4aSHimanshu Madhani if (mcp->mb[1] != 0x7)
565175666f4aSHimanshu Madhani ha->link_data_rate = mcp->mb[1];
565275666f4aSHimanshu Madhani
565375666f4aSHimanshu Madhani if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
565475666f4aSHimanshu Madhani if (mcp->mb[4] & BIT_0)
565575666f4aSHimanshu Madhani ql_log(ql_log_info, vha, 0x11a2,
565675666f4aSHimanshu Madhani "FEC=enabled (data rate).\n");
565775666f4aSHimanshu Madhani }
565875666f4aSHimanshu Madhani
56595f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
56605f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
56613064ff39SMichael Hernandez if (mcp->mb[1] != 0x7)
56623064ff39SMichael Hernandez ha->link_data_rate = mcp->mb[1];
56633064ff39SMichael Hernandez }
56643064ff39SMichael Hernandez
56653064ff39SMichael Hernandez return rval;
56663064ff39SMichael Hernandez }
566709ff701aSSarang Radke
566809ff701aSSarang Radke int
qla81xx_get_port_config(scsi_qla_host_t * vha,uint16_t * mb)566923f2ebd1SSarang Radke qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
567023f2ebd1SSarang Radke {
567123f2ebd1SSarang Radke int rval;
567223f2ebd1SSarang Radke mbx_cmd_t mc;
567323f2ebd1SSarang Radke mbx_cmd_t *mcp = &mc;
567423f2ebd1SSarang Radke struct qla_hw_data *ha = vha->hw;
567523f2ebd1SSarang Radke
56765f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
56775f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
567823f2ebd1SSarang Radke
5679f73cb695SChad Dupuis if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
5680ecc89f25SJoe Carnuccio !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
568123f2ebd1SSarang Radke return QLA_FUNCTION_FAILED;
568223f2ebd1SSarang Radke mcp->mb[0] = MBC_GET_PORT_CONFIG;
568323f2ebd1SSarang Radke mcp->out_mb = MBX_0;
568423f2ebd1SSarang Radke mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
568523f2ebd1SSarang Radke mcp->tov = MBX_TOV_SECONDS;
568623f2ebd1SSarang Radke mcp->flags = 0;
568723f2ebd1SSarang Radke
568823f2ebd1SSarang Radke rval = qla2x00_mailbox_command(vha, mcp);
568923f2ebd1SSarang Radke
569023f2ebd1SSarang Radke if (rval != QLA_SUCCESS) {
56917c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x110a,
56927c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
569323f2ebd1SSarang Radke } else {
569423f2ebd1SSarang Radke /* Copy all bits to preserve original value */
569523f2ebd1SSarang Radke memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
569623f2ebd1SSarang Radke
56975f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
56985f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
569923f2ebd1SSarang Radke }
570023f2ebd1SSarang Radke return rval;
570123f2ebd1SSarang Radke }
570223f2ebd1SSarang Radke
570323f2ebd1SSarang Radke int
qla81xx_set_port_config(scsi_qla_host_t * vha,uint16_t * mb)570423f2ebd1SSarang Radke qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
570523f2ebd1SSarang Radke {
570623f2ebd1SSarang Radke int rval;
570723f2ebd1SSarang Radke mbx_cmd_t mc;
570823f2ebd1SSarang Radke mbx_cmd_t *mcp = &mc;
570923f2ebd1SSarang Radke
57105f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
57115f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
571223f2ebd1SSarang Radke
571323f2ebd1SSarang Radke mcp->mb[0] = MBC_SET_PORT_CONFIG;
571423f2ebd1SSarang Radke /* Copy all bits to preserve original setting */
571523f2ebd1SSarang Radke memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
571623f2ebd1SSarang Radke mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
571723f2ebd1SSarang Radke mcp->in_mb = MBX_0;
571823f2ebd1SSarang Radke mcp->tov = MBX_TOV_SECONDS;
571923f2ebd1SSarang Radke mcp->flags = 0;
572023f2ebd1SSarang Radke rval = qla2x00_mailbox_command(vha, mcp);
572123f2ebd1SSarang Radke
572223f2ebd1SSarang Radke if (rval != QLA_SUCCESS) {
57237c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x110d,
57247c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
572523f2ebd1SSarang Radke } else
57265f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
57275f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
572823f2ebd1SSarang Radke
572923f2ebd1SSarang Radke return rval;
573023f2ebd1SSarang Radke }
573123f2ebd1SSarang Radke
573223f2ebd1SSarang Radke
573323f2ebd1SSarang Radke int
qla24xx_set_fcp_prio(scsi_qla_host_t * vha,uint16_t loop_id,uint16_t priority,uint16_t * mb)573409ff701aSSarang Radke qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
573509ff701aSSarang Radke uint16_t *mb)
573609ff701aSSarang Radke {
573709ff701aSSarang Radke int rval;
573809ff701aSSarang Radke mbx_cmd_t mc;
573909ff701aSSarang Radke mbx_cmd_t *mcp = &mc;
574009ff701aSSarang Radke struct qla_hw_data *ha = vha->hw;
574109ff701aSSarang Radke
57425f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
57435f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
57447c3df132SSaurav Kashyap
574509ff701aSSarang Radke if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
574609ff701aSSarang Radke return QLA_FUNCTION_FAILED;
574709ff701aSSarang Radke
574809ff701aSSarang Radke mcp->mb[0] = MBC_PORT_PARAMS;
574909ff701aSSarang Radke mcp->mb[1] = loop_id;
575009ff701aSSarang Radke if (ha->flags.fcp_prio_enabled)
575109ff701aSSarang Radke mcp->mb[2] = BIT_1;
575209ff701aSSarang Radke else
575309ff701aSSarang Radke mcp->mb[2] = BIT_2;
575409ff701aSSarang Radke mcp->mb[4] = priority & 0xf;
575509ff701aSSarang Radke mcp->mb[9] = vha->vp_idx;
575609ff701aSSarang Radke mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
575709ff701aSSarang Radke mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5758c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
575909ff701aSSarang Radke mcp->flags = 0;
576009ff701aSSarang Radke rval = qla2x00_mailbox_command(vha, mcp);
576109ff701aSSarang Radke if (mb != NULL) {
576209ff701aSSarang Radke mb[0] = mcp->mb[0];
576309ff701aSSarang Radke mb[1] = mcp->mb[1];
576409ff701aSSarang Radke mb[3] = mcp->mb[3];
576509ff701aSSarang Radke mb[4] = mcp->mb[4];
576609ff701aSSarang Radke }
576709ff701aSSarang Radke
576809ff701aSSarang Radke if (rval != QLA_SUCCESS) {
57697c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
577009ff701aSSarang Radke } else {
57715f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
57725f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
577309ff701aSSarang Radke }
577409ff701aSSarang Radke
577509ff701aSSarang Radke return rval;
577609ff701aSSarang Radke }
5777a9083016SGiridhar Malavali
5778a9083016SGiridhar Malavali int
qla2x00_get_thermal_temp(scsi_qla_host_t * vha,uint16_t * temp)5779fe52f6e1SJoe Carnuccio qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
5780794a5691SAndrew Vasquez {
5781fe52f6e1SJoe Carnuccio int rval = QLA_FUNCTION_FAILED;
5782794a5691SAndrew Vasquez struct qla_hw_data *ha = vha->hw;
5783fe52f6e1SJoe Carnuccio uint8_t byte;
5784794a5691SAndrew Vasquez
57851ae47cf3SJoe Carnuccio if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
57861ae47cf3SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1150,
57871ae47cf3SJoe Carnuccio "Thermal not supported by this card.\n");
5788794a5691SAndrew Vasquez return rval;
57891ae47cf3SJoe Carnuccio }
5790fe52f6e1SJoe Carnuccio
57911ae47cf3SJoe Carnuccio if (IS_QLA25XX(ha)) {
57921ae47cf3SJoe Carnuccio if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
57931ae47cf3SJoe Carnuccio ha->pdev->subsystem_device == 0x0175) {
57941ae47cf3SJoe Carnuccio rval = qla2x00_read_sfp(vha, 0, &byte,
57951ae47cf3SJoe Carnuccio 0x98, 0x1, 1, BIT_13|BIT_0);
57961ae47cf3SJoe Carnuccio *temp = byte;
57971ae47cf3SJoe Carnuccio return rval;
57981ae47cf3SJoe Carnuccio }
57991ae47cf3SJoe Carnuccio if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
58001ae47cf3SJoe Carnuccio ha->pdev->subsystem_device == 0x338e) {
58011ae47cf3SJoe Carnuccio rval = qla2x00_read_sfp(vha, 0, &byte,
58021ae47cf3SJoe Carnuccio 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
58031ae47cf3SJoe Carnuccio *temp = byte;
58041ae47cf3SJoe Carnuccio return rval;
58051ae47cf3SJoe Carnuccio }
58061ae47cf3SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x10c9,
58071ae47cf3SJoe Carnuccio "Thermal not supported by this card.\n");
58081ae47cf3SJoe Carnuccio return rval;
58091ae47cf3SJoe Carnuccio }
58101ae47cf3SJoe Carnuccio
58111ae47cf3SJoe Carnuccio if (IS_QLA82XX(ha)) {
58121ae47cf3SJoe Carnuccio *temp = qla82xx_read_temperature(vha);
58131ae47cf3SJoe Carnuccio rval = QLA_SUCCESS;
58141ae47cf3SJoe Carnuccio return rval;
58151ae47cf3SJoe Carnuccio } else if (IS_QLA8044(ha)) {
58161ae47cf3SJoe Carnuccio *temp = qla8044_read_temperature(vha);
58171ae47cf3SJoe Carnuccio rval = QLA_SUCCESS;
58181ae47cf3SJoe Carnuccio return rval;
58191ae47cf3SJoe Carnuccio }
58201ae47cf3SJoe Carnuccio
58211ae47cf3SJoe Carnuccio rval = qla2x00_read_asic_temperature(vha, temp);
5822fe52f6e1SJoe Carnuccio return rval;
5823794a5691SAndrew Vasquez }
5824794a5691SAndrew Vasquez
5825794a5691SAndrew Vasquez int
qla82xx_mbx_intr_enable(scsi_qla_host_t * vha)5826a9083016SGiridhar Malavali qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5827a9083016SGiridhar Malavali {
5828a9083016SGiridhar Malavali int rval;
5829a9083016SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
5830a9083016SGiridhar Malavali mbx_cmd_t mc;
5831a9083016SGiridhar Malavali mbx_cmd_t *mcp = &mc;
5832a9083016SGiridhar Malavali
58335f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
58345f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
58357c3df132SSaurav Kashyap
5836a9083016SGiridhar Malavali if (!IS_FWI2_CAPABLE(ha))
5837a9083016SGiridhar Malavali return QLA_FUNCTION_FAILED;
5838a9083016SGiridhar Malavali
5839a9083016SGiridhar Malavali memset(mcp, 0, sizeof(mbx_cmd_t));
58403711333dSGiridhar Malavali mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5841a9083016SGiridhar Malavali mcp->mb[1] = 1;
5842a9083016SGiridhar Malavali
5843a9083016SGiridhar Malavali mcp->out_mb = MBX_1|MBX_0;
5844a9083016SGiridhar Malavali mcp->in_mb = MBX_0;
5845c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
5846a9083016SGiridhar Malavali mcp->flags = 0;
5847a9083016SGiridhar Malavali
5848a9083016SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
5849a9083016SGiridhar Malavali if (rval != QLA_SUCCESS) {
58507c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1016,
58517c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5852a9083016SGiridhar Malavali } else {
58535f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
58545f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
5855a9083016SGiridhar Malavali }
5856a9083016SGiridhar Malavali
5857a9083016SGiridhar Malavali return rval;
5858a9083016SGiridhar Malavali }
5859a9083016SGiridhar Malavali
5860a9083016SGiridhar Malavali int
qla82xx_mbx_intr_disable(scsi_qla_host_t * vha)5861a9083016SGiridhar Malavali qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5862a9083016SGiridhar Malavali {
5863a9083016SGiridhar Malavali int rval;
5864a9083016SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
5865a9083016SGiridhar Malavali mbx_cmd_t mc;
5866a9083016SGiridhar Malavali mbx_cmd_t *mcp = &mc;
5867a9083016SGiridhar Malavali
58685f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
58695f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
58707c3df132SSaurav Kashyap
58717ec0effdSAtul Deshmukh if (!IS_P3P_TYPE(ha))
5872a9083016SGiridhar Malavali return QLA_FUNCTION_FAILED;
5873a9083016SGiridhar Malavali
5874a9083016SGiridhar Malavali memset(mcp, 0, sizeof(mbx_cmd_t));
58753711333dSGiridhar Malavali mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5876a9083016SGiridhar Malavali mcp->mb[1] = 0;
5877a9083016SGiridhar Malavali
5878a9083016SGiridhar Malavali mcp->out_mb = MBX_1|MBX_0;
5879a9083016SGiridhar Malavali mcp->in_mb = MBX_0;
5880c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
5881a9083016SGiridhar Malavali mcp->flags = 0;
5882a9083016SGiridhar Malavali
5883a9083016SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
5884a9083016SGiridhar Malavali if (rval != QLA_SUCCESS) {
58857c3df132SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x100c,
58867c3df132SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5887a9083016SGiridhar Malavali } else {
58885f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
58895f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
5890a9083016SGiridhar Malavali }
5891a9083016SGiridhar Malavali
5892a9083016SGiridhar Malavali return rval;
5893a9083016SGiridhar Malavali }
589408de2844SGiridhar Malavali
589508de2844SGiridhar Malavali int
qla82xx_md_get_template_size(scsi_qla_host_t * vha)589608de2844SGiridhar Malavali qla82xx_md_get_template_size(scsi_qla_host_t *vha)
589708de2844SGiridhar Malavali {
589808de2844SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
589908de2844SGiridhar Malavali mbx_cmd_t mc;
590008de2844SGiridhar Malavali mbx_cmd_t *mcp = &mc;
590108de2844SGiridhar Malavali int rval = QLA_FUNCTION_FAILED;
590208de2844SGiridhar Malavali
59035f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
59045f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
590508de2844SGiridhar Malavali
590608de2844SGiridhar Malavali memset(mcp->mb, 0 , sizeof(mcp->mb));
590708de2844SGiridhar Malavali mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
590808de2844SGiridhar Malavali mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
590908de2844SGiridhar Malavali mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
591008de2844SGiridhar Malavali mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
591108de2844SGiridhar Malavali
591208de2844SGiridhar Malavali mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
591308de2844SGiridhar Malavali mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
591408de2844SGiridhar Malavali MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
591508de2844SGiridhar Malavali
591608de2844SGiridhar Malavali mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
591708de2844SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
591808de2844SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
591908de2844SGiridhar Malavali
592008de2844SGiridhar Malavali /* Always copy back return mailbox values. */
592108de2844SGiridhar Malavali if (rval != QLA_SUCCESS) {
592208de2844SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1120,
592308de2844SGiridhar Malavali "mailbox command FAILED=0x%x, subcode=%x.\n",
592408de2844SGiridhar Malavali (mcp->mb[1] << 16) | mcp->mb[0],
592508de2844SGiridhar Malavali (mcp->mb[3] << 16) | mcp->mb[2]);
592608de2844SGiridhar Malavali } else {
59275f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
59285f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
592908de2844SGiridhar Malavali ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
593008de2844SGiridhar Malavali if (!ha->md_template_size) {
593108de2844SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1122,
593208de2844SGiridhar Malavali "Null template size obtained.\n");
593308de2844SGiridhar Malavali rval = QLA_FUNCTION_FAILED;
593408de2844SGiridhar Malavali }
593508de2844SGiridhar Malavali }
593608de2844SGiridhar Malavali return rval;
593708de2844SGiridhar Malavali }
593808de2844SGiridhar Malavali
593908de2844SGiridhar Malavali int
qla82xx_md_get_template(scsi_qla_host_t * vha)594008de2844SGiridhar Malavali qla82xx_md_get_template(scsi_qla_host_t *vha)
594108de2844SGiridhar Malavali {
594208de2844SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
594308de2844SGiridhar Malavali mbx_cmd_t mc;
594408de2844SGiridhar Malavali mbx_cmd_t *mcp = &mc;
594508de2844SGiridhar Malavali int rval = QLA_FUNCTION_FAILED;
594608de2844SGiridhar Malavali
59475f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
59485f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
594908de2844SGiridhar Malavali
595008de2844SGiridhar Malavali ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
595108de2844SGiridhar Malavali ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
595208de2844SGiridhar Malavali if (!ha->md_tmplt_hdr) {
595308de2844SGiridhar Malavali ql_log(ql_log_warn, vha, 0x1124,
595408de2844SGiridhar Malavali "Unable to allocate memory for Minidump template.\n");
595508de2844SGiridhar Malavali return rval;
595608de2844SGiridhar Malavali }
595708de2844SGiridhar Malavali
595808de2844SGiridhar Malavali memset(mcp->mb, 0 , sizeof(mcp->mb));
595908de2844SGiridhar Malavali mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
596008de2844SGiridhar Malavali mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
596108de2844SGiridhar Malavali mcp->mb[2] = LSW(RQST_TMPLT);
596208de2844SGiridhar Malavali mcp->mb[3] = MSW(RQST_TMPLT);
596308de2844SGiridhar Malavali mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
596408de2844SGiridhar Malavali mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
596508de2844SGiridhar Malavali mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
596608de2844SGiridhar Malavali mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
596708de2844SGiridhar Malavali mcp->mb[8] = LSW(ha->md_template_size);
596808de2844SGiridhar Malavali mcp->mb[9] = MSW(ha->md_template_size);
596908de2844SGiridhar Malavali
597008de2844SGiridhar Malavali mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
597108de2844SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
597208de2844SGiridhar Malavali mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
597308de2844SGiridhar Malavali MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
597408de2844SGiridhar Malavali mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
597508de2844SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
597608de2844SGiridhar Malavali
597708de2844SGiridhar Malavali if (rval != QLA_SUCCESS) {
597808de2844SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1125,
597908de2844SGiridhar Malavali "mailbox command FAILED=0x%x, subcode=%x.\n",
598008de2844SGiridhar Malavali ((mcp->mb[1] << 16) | mcp->mb[0]),
598108de2844SGiridhar Malavali ((mcp->mb[3] << 16) | mcp->mb[2]));
598208de2844SGiridhar Malavali } else
59835f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
59845f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
598508de2844SGiridhar Malavali return rval;
598608de2844SGiridhar Malavali }
5987999916dcSSaurav Kashyap
5988999916dcSSaurav Kashyap int
qla8044_md_get_template(scsi_qla_host_t * vha)59897ec0effdSAtul Deshmukh qla8044_md_get_template(scsi_qla_host_t *vha)
59907ec0effdSAtul Deshmukh {
59917ec0effdSAtul Deshmukh struct qla_hw_data *ha = vha->hw;
59927ec0effdSAtul Deshmukh mbx_cmd_t mc;
59937ec0effdSAtul Deshmukh mbx_cmd_t *mcp = &mc;
59947ec0effdSAtul Deshmukh int rval = QLA_FUNCTION_FAILED;
59957ec0effdSAtul Deshmukh int offset = 0, size = MINIDUMP_SIZE_36K;
5996bd432bb5SBart Van Assche
59977ec0effdSAtul Deshmukh ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
59987ec0effdSAtul Deshmukh "Entered %s.\n", __func__);
59997ec0effdSAtul Deshmukh
60007ec0effdSAtul Deshmukh ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
60017ec0effdSAtul Deshmukh ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
60027ec0effdSAtul Deshmukh if (!ha->md_tmplt_hdr) {
60037ec0effdSAtul Deshmukh ql_log(ql_log_warn, vha, 0xb11b,
60047ec0effdSAtul Deshmukh "Unable to allocate memory for Minidump template.\n");
60057ec0effdSAtul Deshmukh return rval;
60067ec0effdSAtul Deshmukh }
60077ec0effdSAtul Deshmukh
60087ec0effdSAtul Deshmukh memset(mcp->mb, 0 , sizeof(mcp->mb));
60097ec0effdSAtul Deshmukh while (offset < ha->md_template_size) {
60107ec0effdSAtul Deshmukh mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
60117ec0effdSAtul Deshmukh mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
60127ec0effdSAtul Deshmukh mcp->mb[2] = LSW(RQST_TMPLT);
60137ec0effdSAtul Deshmukh mcp->mb[3] = MSW(RQST_TMPLT);
60147ec0effdSAtul Deshmukh mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
60157ec0effdSAtul Deshmukh mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
60167ec0effdSAtul Deshmukh mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
60177ec0effdSAtul Deshmukh mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
60187ec0effdSAtul Deshmukh mcp->mb[8] = LSW(size);
60197ec0effdSAtul Deshmukh mcp->mb[9] = MSW(size);
60207ec0effdSAtul Deshmukh mcp->mb[10] = offset & 0x0000FFFF;
60217ec0effdSAtul Deshmukh mcp->mb[11] = offset & 0xFFFF0000;
60227ec0effdSAtul Deshmukh mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
60237ec0effdSAtul Deshmukh mcp->tov = MBX_TOV_SECONDS;
60247ec0effdSAtul Deshmukh mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
60257ec0effdSAtul Deshmukh MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
60267ec0effdSAtul Deshmukh mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
60277ec0effdSAtul Deshmukh rval = qla2x00_mailbox_command(vha, mcp);
60287ec0effdSAtul Deshmukh
60297ec0effdSAtul Deshmukh if (rval != QLA_SUCCESS) {
60307ec0effdSAtul Deshmukh ql_dbg(ql_dbg_mbx, vha, 0xb11c,
60317ec0effdSAtul Deshmukh "mailbox command FAILED=0x%x, subcode=%x.\n",
60327ec0effdSAtul Deshmukh ((mcp->mb[1] << 16) | mcp->mb[0]),
60337ec0effdSAtul Deshmukh ((mcp->mb[3] << 16) | mcp->mb[2]));
60347ec0effdSAtul Deshmukh return rval;
60357ec0effdSAtul Deshmukh } else
60367ec0effdSAtul Deshmukh ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
60377ec0effdSAtul Deshmukh "Done %s.\n", __func__);
60387ec0effdSAtul Deshmukh offset = offset + size;
60397ec0effdSAtul Deshmukh }
60407ec0effdSAtul Deshmukh return rval;
60417ec0effdSAtul Deshmukh }
60427ec0effdSAtul Deshmukh
60437ec0effdSAtul Deshmukh int
qla81xx_set_led_config(scsi_qla_host_t * vha,uint16_t * led_cfg)60446246b8a1SGiridhar Malavali qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
60456246b8a1SGiridhar Malavali {
60466246b8a1SGiridhar Malavali int rval;
60476246b8a1SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
60486246b8a1SGiridhar Malavali mbx_cmd_t mc;
60496246b8a1SGiridhar Malavali mbx_cmd_t *mcp = &mc;
60506246b8a1SGiridhar Malavali
60516246b8a1SGiridhar Malavali if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
60526246b8a1SGiridhar Malavali return QLA_FUNCTION_FAILED;
60536246b8a1SGiridhar Malavali
60545f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
60555f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
60566246b8a1SGiridhar Malavali
60576246b8a1SGiridhar Malavali memset(mcp, 0, sizeof(mbx_cmd_t));
60586246b8a1SGiridhar Malavali mcp->mb[0] = MBC_SET_LED_CONFIG;
60596246b8a1SGiridhar Malavali mcp->mb[1] = led_cfg[0];
60606246b8a1SGiridhar Malavali mcp->mb[2] = led_cfg[1];
60616246b8a1SGiridhar Malavali if (IS_QLA8031(ha)) {
60626246b8a1SGiridhar Malavali mcp->mb[3] = led_cfg[2];
60636246b8a1SGiridhar Malavali mcp->mb[4] = led_cfg[3];
60646246b8a1SGiridhar Malavali mcp->mb[5] = led_cfg[4];
60656246b8a1SGiridhar Malavali mcp->mb[6] = led_cfg[5];
60666246b8a1SGiridhar Malavali }
60676246b8a1SGiridhar Malavali
60686246b8a1SGiridhar Malavali mcp->out_mb = MBX_2|MBX_1|MBX_0;
60696246b8a1SGiridhar Malavali if (IS_QLA8031(ha))
60706246b8a1SGiridhar Malavali mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
60716246b8a1SGiridhar Malavali mcp->in_mb = MBX_0;
6072c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
60736246b8a1SGiridhar Malavali mcp->flags = 0;
60746246b8a1SGiridhar Malavali
60756246b8a1SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
60766246b8a1SGiridhar Malavali if (rval != QLA_SUCCESS) {
60776246b8a1SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1134,
60786246b8a1SGiridhar Malavali "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
60796246b8a1SGiridhar Malavali } else {
60805f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
60815f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
60826246b8a1SGiridhar Malavali }
60836246b8a1SGiridhar Malavali
60846246b8a1SGiridhar Malavali return rval;
60856246b8a1SGiridhar Malavali }
60866246b8a1SGiridhar Malavali
60876246b8a1SGiridhar Malavali int
qla81xx_get_led_config(scsi_qla_host_t * vha,uint16_t * led_cfg)60886246b8a1SGiridhar Malavali qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
60896246b8a1SGiridhar Malavali {
60906246b8a1SGiridhar Malavali int rval;
60916246b8a1SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
60926246b8a1SGiridhar Malavali mbx_cmd_t mc;
60936246b8a1SGiridhar Malavali mbx_cmd_t *mcp = &mc;
60946246b8a1SGiridhar Malavali
60956246b8a1SGiridhar Malavali if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
60966246b8a1SGiridhar Malavali return QLA_FUNCTION_FAILED;
60976246b8a1SGiridhar Malavali
60985f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
60995f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
61006246b8a1SGiridhar Malavali
61016246b8a1SGiridhar Malavali memset(mcp, 0, sizeof(mbx_cmd_t));
61026246b8a1SGiridhar Malavali mcp->mb[0] = MBC_GET_LED_CONFIG;
61036246b8a1SGiridhar Malavali
61046246b8a1SGiridhar Malavali mcp->out_mb = MBX_0;
61056246b8a1SGiridhar Malavali mcp->in_mb = MBX_2|MBX_1|MBX_0;
61066246b8a1SGiridhar Malavali if (IS_QLA8031(ha))
61076246b8a1SGiridhar Malavali mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
6108c314a014SEnzo Matsumiya mcp->tov = MBX_TOV_SECONDS;
61096246b8a1SGiridhar Malavali mcp->flags = 0;
61106246b8a1SGiridhar Malavali
61116246b8a1SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
61126246b8a1SGiridhar Malavali if (rval != QLA_SUCCESS) {
61136246b8a1SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1137,
61146246b8a1SGiridhar Malavali "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
61156246b8a1SGiridhar Malavali } else {
61166246b8a1SGiridhar Malavali led_cfg[0] = mcp->mb[1];
61176246b8a1SGiridhar Malavali led_cfg[1] = mcp->mb[2];
61186246b8a1SGiridhar Malavali if (IS_QLA8031(ha)) {
61196246b8a1SGiridhar Malavali led_cfg[2] = mcp->mb[3];
61206246b8a1SGiridhar Malavali led_cfg[3] = mcp->mb[4];
61216246b8a1SGiridhar Malavali led_cfg[4] = mcp->mb[5];
61226246b8a1SGiridhar Malavali led_cfg[5] = mcp->mb[6];
61236246b8a1SGiridhar Malavali }
61245f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
61255f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
61266246b8a1SGiridhar Malavali }
61276246b8a1SGiridhar Malavali
61286246b8a1SGiridhar Malavali return rval;
61296246b8a1SGiridhar Malavali }
61306246b8a1SGiridhar Malavali
61316246b8a1SGiridhar Malavali int
qla82xx_mbx_beacon_ctl(scsi_qla_host_t * vha,int enable)6132999916dcSSaurav Kashyap qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
6133999916dcSSaurav Kashyap {
6134999916dcSSaurav Kashyap int rval;
6135999916dcSSaurav Kashyap struct qla_hw_data *ha = vha->hw;
6136999916dcSSaurav Kashyap mbx_cmd_t mc;
6137999916dcSSaurav Kashyap mbx_cmd_t *mcp = &mc;
6138999916dcSSaurav Kashyap
61397ec0effdSAtul Deshmukh if (!IS_P3P_TYPE(ha))
6140999916dcSSaurav Kashyap return QLA_FUNCTION_FAILED;
6141999916dcSSaurav Kashyap
61425f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
6143999916dcSSaurav Kashyap "Entered %s.\n", __func__);
6144999916dcSSaurav Kashyap
6145999916dcSSaurav Kashyap memset(mcp, 0, sizeof(mbx_cmd_t));
6146999916dcSSaurav Kashyap mcp->mb[0] = MBC_SET_LED_CONFIG;
6147999916dcSSaurav Kashyap if (enable)
6148999916dcSSaurav Kashyap mcp->mb[7] = 0xE;
6149999916dcSSaurav Kashyap else
6150999916dcSSaurav Kashyap mcp->mb[7] = 0xD;
6151999916dcSSaurav Kashyap
6152999916dcSSaurav Kashyap mcp->out_mb = MBX_7|MBX_0;
6153999916dcSSaurav Kashyap mcp->in_mb = MBX_0;
61546246b8a1SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
6155999916dcSSaurav Kashyap mcp->flags = 0;
6156999916dcSSaurav Kashyap
6157999916dcSSaurav Kashyap rval = qla2x00_mailbox_command(vha, mcp);
6158999916dcSSaurav Kashyap if (rval != QLA_SUCCESS) {
6159999916dcSSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x1128,
6160999916dcSSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
6161999916dcSSaurav Kashyap } else {
61625f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
6163999916dcSSaurav Kashyap "Done %s.\n", __func__);
6164999916dcSSaurav Kashyap }
6165999916dcSSaurav Kashyap
6166999916dcSSaurav Kashyap return rval;
6167999916dcSSaurav Kashyap }
61686246b8a1SGiridhar Malavali
61696246b8a1SGiridhar Malavali int
qla83xx_wr_reg(scsi_qla_host_t * vha,uint32_t reg,uint32_t data)61707d613ac6SSantosh Vernekar qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
61716246b8a1SGiridhar Malavali {
61726246b8a1SGiridhar Malavali int rval;
61736246b8a1SGiridhar Malavali struct qla_hw_data *ha = vha->hw;
61746246b8a1SGiridhar Malavali mbx_cmd_t mc;
61756246b8a1SGiridhar Malavali mbx_cmd_t *mcp = &mc;
61766246b8a1SGiridhar Malavali
6177ecc89f25SJoe Carnuccio if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
61786246b8a1SGiridhar Malavali return QLA_FUNCTION_FAILED;
61796246b8a1SGiridhar Malavali
61805f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
61815f28d2d7SSaurav Kashyap "Entered %s.\n", __func__);
61826246b8a1SGiridhar Malavali
61836246b8a1SGiridhar Malavali mcp->mb[0] = MBC_WRITE_REMOTE_REG;
61846246b8a1SGiridhar Malavali mcp->mb[1] = LSW(reg);
61856246b8a1SGiridhar Malavali mcp->mb[2] = MSW(reg);
61866246b8a1SGiridhar Malavali mcp->mb[3] = LSW(data);
61876246b8a1SGiridhar Malavali mcp->mb[4] = MSW(data);
61886246b8a1SGiridhar Malavali mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
61896246b8a1SGiridhar Malavali
61906246b8a1SGiridhar Malavali mcp->in_mb = MBX_1|MBX_0;
61916246b8a1SGiridhar Malavali mcp->tov = MBX_TOV_SECONDS;
61926246b8a1SGiridhar Malavali mcp->flags = 0;
61936246b8a1SGiridhar Malavali rval = qla2x00_mailbox_command(vha, mcp);
61946246b8a1SGiridhar Malavali
61956246b8a1SGiridhar Malavali if (rval != QLA_SUCCESS) {
61966246b8a1SGiridhar Malavali ql_dbg(ql_dbg_mbx, vha, 0x1131,
61976246b8a1SGiridhar Malavali "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
61986246b8a1SGiridhar Malavali } else {
61995f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
62006246b8a1SGiridhar Malavali "Done %s.\n", __func__);
62016246b8a1SGiridhar Malavali }
6202af11f64dSAndrew Vasquez
62036246b8a1SGiridhar Malavali return rval;
62046246b8a1SGiridhar Malavali }
6205af11f64dSAndrew Vasquez
6206af11f64dSAndrew Vasquez int
qla2x00_port_logout(scsi_qla_host_t * vha,struct fc_port * fcport)6207af11f64dSAndrew Vasquez qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
6208af11f64dSAndrew Vasquez {
6209af11f64dSAndrew Vasquez int rval;
6210af11f64dSAndrew Vasquez struct qla_hw_data *ha = vha->hw;
6211af11f64dSAndrew Vasquez mbx_cmd_t mc;
6212af11f64dSAndrew Vasquez mbx_cmd_t *mcp = &mc;
6213af11f64dSAndrew Vasquez
6214af11f64dSAndrew Vasquez if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
62155f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
6216af11f64dSAndrew Vasquez "Implicit LOGO Unsupported.\n");
6217af11f64dSAndrew Vasquez return QLA_FUNCTION_FAILED;
6218af11f64dSAndrew Vasquez }
6219af11f64dSAndrew Vasquez
6220af11f64dSAndrew Vasquez
62215f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
62225f28d2d7SSaurav Kashyap "Entering %s.\n", __func__);
6223af11f64dSAndrew Vasquez
6224af11f64dSAndrew Vasquez /* Perform Implicit LOGO. */
6225af11f64dSAndrew Vasquez mcp->mb[0] = MBC_PORT_LOGOUT;
6226af11f64dSAndrew Vasquez mcp->mb[1] = fcport->loop_id;
6227af11f64dSAndrew Vasquez mcp->mb[10] = BIT_15;
6228af11f64dSAndrew Vasquez mcp->out_mb = MBX_10|MBX_1|MBX_0;
6229af11f64dSAndrew Vasquez mcp->in_mb = MBX_0;
6230af11f64dSAndrew Vasquez mcp->tov = MBX_TOV_SECONDS;
6231af11f64dSAndrew Vasquez mcp->flags = 0;
6232af11f64dSAndrew Vasquez rval = qla2x00_mailbox_command(vha, mcp);
6233af11f64dSAndrew Vasquez if (rval != QLA_SUCCESS)
6234af11f64dSAndrew Vasquez ql_dbg(ql_dbg_mbx, vha, 0x113d,
6235af11f64dSAndrew Vasquez "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
6236af11f64dSAndrew Vasquez else
62375f28d2d7SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
62385f28d2d7SSaurav Kashyap "Done %s.\n", __func__);
6239af11f64dSAndrew Vasquez
6240af11f64dSAndrew Vasquez return rval;
6241af11f64dSAndrew Vasquez }
6242af11f64dSAndrew Vasquez
62437d613ac6SSantosh Vernekar int
qla83xx_rd_reg(scsi_qla_host_t * vha,uint32_t reg,uint32_t * data)62447d613ac6SSantosh Vernekar qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
62457d613ac6SSantosh Vernekar {
62467d613ac6SSantosh Vernekar int rval;
62477d613ac6SSantosh Vernekar mbx_cmd_t mc;
62487d613ac6SSantosh Vernekar mbx_cmd_t *mcp = &mc;
62497d613ac6SSantosh Vernekar struct qla_hw_data *ha = vha->hw;
62507d613ac6SSantosh Vernekar unsigned long retry_max_time = jiffies + (2 * HZ);
62517d613ac6SSantosh Vernekar
6252ecc89f25SJoe Carnuccio if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
62537d613ac6SSantosh Vernekar return QLA_FUNCTION_FAILED;
62547d613ac6SSantosh Vernekar
62557d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
62567d613ac6SSantosh Vernekar
62577d613ac6SSantosh Vernekar retry_rd_reg:
62587d613ac6SSantosh Vernekar mcp->mb[0] = MBC_READ_REMOTE_REG;
62597d613ac6SSantosh Vernekar mcp->mb[1] = LSW(reg);
62607d613ac6SSantosh Vernekar mcp->mb[2] = MSW(reg);
62617d613ac6SSantosh Vernekar mcp->out_mb = MBX_2|MBX_1|MBX_0;
62627d613ac6SSantosh Vernekar mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
62637d613ac6SSantosh Vernekar mcp->tov = MBX_TOV_SECONDS;
62647d613ac6SSantosh Vernekar mcp->flags = 0;
62657d613ac6SSantosh Vernekar rval = qla2x00_mailbox_command(vha, mcp);
62667d613ac6SSantosh Vernekar
62677d613ac6SSantosh Vernekar if (rval != QLA_SUCCESS) {
62687d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x114c,
62697d613ac6SSantosh Vernekar "Failed=%x mb[0]=%x mb[1]=%x.\n",
62707d613ac6SSantosh Vernekar rval, mcp->mb[0], mcp->mb[1]);
62717d613ac6SSantosh Vernekar } else {
62727d613ac6SSantosh Vernekar *data = (mcp->mb[3] | (mcp->mb[4] << 16));
62737d613ac6SSantosh Vernekar if (*data == QLA8XXX_BAD_VALUE) {
62747d613ac6SSantosh Vernekar /*
62757d613ac6SSantosh Vernekar * During soft-reset CAMRAM register reads might
62767d613ac6SSantosh Vernekar * return 0xbad0bad0. So retry for MAX of 2 sec
62777d613ac6SSantosh Vernekar * while reading camram registers.
62787d613ac6SSantosh Vernekar */
62797d613ac6SSantosh Vernekar if (time_after(jiffies, retry_max_time)) {
62807d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1141,
62817d613ac6SSantosh Vernekar "Failure to read CAMRAM register. "
62827d613ac6SSantosh Vernekar "data=0x%x.\n", *data);
62837d613ac6SSantosh Vernekar return QLA_FUNCTION_FAILED;
62847d613ac6SSantosh Vernekar }
62857d613ac6SSantosh Vernekar msleep(100);
62867d613ac6SSantosh Vernekar goto retry_rd_reg;
62877d613ac6SSantosh Vernekar }
62887d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
62897d613ac6SSantosh Vernekar }
62907d613ac6SSantosh Vernekar
62917d613ac6SSantosh Vernekar return rval;
62927d613ac6SSantosh Vernekar }
62937d613ac6SSantosh Vernekar
62947d613ac6SSantosh Vernekar int
qla83xx_restart_nic_firmware(scsi_qla_host_t * vha)62957d613ac6SSantosh Vernekar qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
62967d613ac6SSantosh Vernekar {
62977d613ac6SSantosh Vernekar int rval;
62987d613ac6SSantosh Vernekar mbx_cmd_t mc;
62997d613ac6SSantosh Vernekar mbx_cmd_t *mcp = &mc;
63007d613ac6SSantosh Vernekar struct qla_hw_data *ha = vha->hw;
63017d613ac6SSantosh Vernekar
6302ecc89f25SJoe Carnuccio if (!IS_QLA83XX(ha))
63037d613ac6SSantosh Vernekar return QLA_FUNCTION_FAILED;
63047d613ac6SSantosh Vernekar
63057d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
63067d613ac6SSantosh Vernekar
63077d613ac6SSantosh Vernekar mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
63087d613ac6SSantosh Vernekar mcp->out_mb = MBX_0;
63097d613ac6SSantosh Vernekar mcp->in_mb = MBX_1|MBX_0;
63107d613ac6SSantosh Vernekar mcp->tov = MBX_TOV_SECONDS;
63117d613ac6SSantosh Vernekar mcp->flags = 0;
63127d613ac6SSantosh Vernekar rval = qla2x00_mailbox_command(vha, mcp);
63137d613ac6SSantosh Vernekar
63147d613ac6SSantosh Vernekar if (rval != QLA_SUCCESS) {
63157d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1144,
63167d613ac6SSantosh Vernekar "Failed=%x mb[0]=%x mb[1]=%x.\n",
63177d613ac6SSantosh Vernekar rval, mcp->mb[0], mcp->mb[1]);
63188ae17876SBart Van Assche qla2xxx_dump_fw(vha);
63197d613ac6SSantosh Vernekar } else {
63207d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
63217d613ac6SSantosh Vernekar }
63227d613ac6SSantosh Vernekar
63237d613ac6SSantosh Vernekar return rval;
63247d613ac6SSantosh Vernekar }
63257d613ac6SSantosh Vernekar
63267d613ac6SSantosh Vernekar int
qla83xx_access_control(scsi_qla_host_t * vha,uint16_t options,uint32_t start_addr,uint32_t end_addr,uint16_t * sector_size)63277d613ac6SSantosh Vernekar qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
63287d613ac6SSantosh Vernekar uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
63297d613ac6SSantosh Vernekar {
63307d613ac6SSantosh Vernekar int rval;
63317d613ac6SSantosh Vernekar mbx_cmd_t mc;
63327d613ac6SSantosh Vernekar mbx_cmd_t *mcp = &mc;
63337d613ac6SSantosh Vernekar uint8_t subcode = (uint8_t)options;
63347d613ac6SSantosh Vernekar struct qla_hw_data *ha = vha->hw;
63357d613ac6SSantosh Vernekar
63367d613ac6SSantosh Vernekar if (!IS_QLA8031(ha))
63377d613ac6SSantosh Vernekar return QLA_FUNCTION_FAILED;
63387d613ac6SSantosh Vernekar
63397d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
63407d613ac6SSantosh Vernekar
63417d613ac6SSantosh Vernekar mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
63427d613ac6SSantosh Vernekar mcp->mb[1] = options;
63437d613ac6SSantosh Vernekar mcp->out_mb = MBX_1|MBX_0;
63447d613ac6SSantosh Vernekar if (subcode & BIT_2) {
63457d613ac6SSantosh Vernekar mcp->mb[2] = LSW(start_addr);
63467d613ac6SSantosh Vernekar mcp->mb[3] = MSW(start_addr);
63477d613ac6SSantosh Vernekar mcp->mb[4] = LSW(end_addr);
63487d613ac6SSantosh Vernekar mcp->mb[5] = MSW(end_addr);
63497d613ac6SSantosh Vernekar mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
63507d613ac6SSantosh Vernekar }
63517d613ac6SSantosh Vernekar mcp->in_mb = MBX_2|MBX_1|MBX_0;
63527d613ac6SSantosh Vernekar if (!(subcode & (BIT_2 | BIT_5)))
63537d613ac6SSantosh Vernekar mcp->in_mb |= MBX_4|MBX_3;
63547d613ac6SSantosh Vernekar mcp->tov = MBX_TOV_SECONDS;
63557d613ac6SSantosh Vernekar mcp->flags = 0;
63567d613ac6SSantosh Vernekar rval = qla2x00_mailbox_command(vha, mcp);
63577d613ac6SSantosh Vernekar
63587d613ac6SSantosh Vernekar if (rval != QLA_SUCCESS) {
63597d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1147,
63607d613ac6SSantosh Vernekar "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
63617d613ac6SSantosh Vernekar rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
63627d613ac6SSantosh Vernekar mcp->mb[4]);
63638ae17876SBart Van Assche qla2xxx_dump_fw(vha);
63647d613ac6SSantosh Vernekar } else {
63657d613ac6SSantosh Vernekar if (subcode & BIT_5)
63667d613ac6SSantosh Vernekar *sector_size = mcp->mb[1];
63677d613ac6SSantosh Vernekar else if (subcode & (BIT_6 | BIT_7)) {
63687d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1148,
63697d613ac6SSantosh Vernekar "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
63707d613ac6SSantosh Vernekar } else if (subcode & (BIT_3 | BIT_4)) {
63717d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x1149,
63727d613ac6SSantosh Vernekar "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
63737d613ac6SSantosh Vernekar }
63747d613ac6SSantosh Vernekar ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
63757d613ac6SSantosh Vernekar }
63767d613ac6SSantosh Vernekar
63777d613ac6SSantosh Vernekar return rval;
63787d613ac6SSantosh Vernekar }
637981178772SSaurav Kashyap
638081178772SSaurav Kashyap int
qla2x00_dump_mctp_data(scsi_qla_host_t * vha,dma_addr_t req_dma,uint32_t addr,uint32_t size)638181178772SSaurav Kashyap qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
638281178772SSaurav Kashyap uint32_t size)
638381178772SSaurav Kashyap {
638481178772SSaurav Kashyap int rval;
638581178772SSaurav Kashyap mbx_cmd_t mc;
638681178772SSaurav Kashyap mbx_cmd_t *mcp = &mc;
638781178772SSaurav Kashyap
638881178772SSaurav Kashyap if (!IS_MCTP_CAPABLE(vha->hw))
638981178772SSaurav Kashyap return QLA_FUNCTION_FAILED;
639081178772SSaurav Kashyap
639181178772SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
639281178772SSaurav Kashyap "Entered %s.\n", __func__);
639381178772SSaurav Kashyap
639481178772SSaurav Kashyap mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
639581178772SSaurav Kashyap mcp->mb[1] = LSW(addr);
639681178772SSaurav Kashyap mcp->mb[2] = MSW(req_dma);
639781178772SSaurav Kashyap mcp->mb[3] = LSW(req_dma);
639881178772SSaurav Kashyap mcp->mb[4] = MSW(size);
639981178772SSaurav Kashyap mcp->mb[5] = LSW(size);
640081178772SSaurav Kashyap mcp->mb[6] = MSW(MSD(req_dma));
640181178772SSaurav Kashyap mcp->mb[7] = LSW(MSD(req_dma));
640281178772SSaurav Kashyap mcp->mb[8] = MSW(addr);
640381178772SSaurav Kashyap /* Setting RAM ID to valid */
640481178772SSaurav Kashyap /* For MCTP RAM ID is 0x40 */
6405641e0efdSQuinn Tran mcp->mb[10] = BIT_7 | 0x40;
640681178772SSaurav Kashyap
640781178772SSaurav Kashyap mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
640881178772SSaurav Kashyap MBX_0;
640981178772SSaurav Kashyap
641081178772SSaurav Kashyap mcp->in_mb = MBX_0;
641181178772SSaurav Kashyap mcp->tov = MBX_TOV_SECONDS;
641281178772SSaurav Kashyap mcp->flags = 0;
641381178772SSaurav Kashyap rval = qla2x00_mailbox_command(vha, mcp);
641481178772SSaurav Kashyap
641581178772SSaurav Kashyap if (rval != QLA_SUCCESS) {
641681178772SSaurav Kashyap ql_dbg(ql_dbg_mbx, vha, 0x114e,
641781178772SSaurav Kashyap "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
641881178772SSaurav Kashyap } else {
641981178772SSaurav Kashyap ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
642081178772SSaurav Kashyap "Done %s.\n", __func__);
642181178772SSaurav Kashyap }
642281178772SSaurav Kashyap
642381178772SSaurav Kashyap return rval;
642481178772SSaurav Kashyap }
6425ec891462SJoe Carnuccio
6426ec891462SJoe Carnuccio int
qla26xx_dport_diagnostics(scsi_qla_host_t * vha,void * dd_buf,uint size,uint options)6427ec891462SJoe Carnuccio qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
6428ec891462SJoe Carnuccio void *dd_buf, uint size, uint options)
6429ec891462SJoe Carnuccio {
6430ec891462SJoe Carnuccio int rval;
6431ec891462SJoe Carnuccio mbx_cmd_t mc;
6432ec891462SJoe Carnuccio mbx_cmd_t *mcp = &mc;
6433ec891462SJoe Carnuccio dma_addr_t dd_dma;
6434ec891462SJoe Carnuccio
6435ecc89f25SJoe Carnuccio if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
6436ecc89f25SJoe Carnuccio !IS_QLA28XX(vha->hw))
6437ec891462SJoe Carnuccio return QLA_FUNCTION_FAILED;
6438ec891462SJoe Carnuccio
643983548fe2SQuinn Tran ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
6440ec891462SJoe Carnuccio "Entered %s.\n", __func__);
6441ec891462SJoe Carnuccio
6442ec891462SJoe Carnuccio dd_dma = dma_map_single(&vha->hw->pdev->dev,
6443ec891462SJoe Carnuccio dd_buf, size, DMA_FROM_DEVICE);
64440b2ce198SPan Bian if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
6445ec891462SJoe Carnuccio ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
6446ec891462SJoe Carnuccio return QLA_MEMORY_ALLOC_FAILED;
6447ec891462SJoe Carnuccio }
6448ec891462SJoe Carnuccio
6449ec891462SJoe Carnuccio memset(dd_buf, 0, size);
6450ec891462SJoe Carnuccio
6451ec891462SJoe Carnuccio mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
6452ec891462SJoe Carnuccio mcp->mb[1] = options;
6453ec891462SJoe Carnuccio mcp->mb[2] = MSW(LSD(dd_dma));
6454ec891462SJoe Carnuccio mcp->mb[3] = LSW(LSD(dd_dma));
6455ec891462SJoe Carnuccio mcp->mb[6] = MSW(MSD(dd_dma));
6456ec891462SJoe Carnuccio mcp->mb[7] = LSW(MSD(dd_dma));
6457ec891462SJoe Carnuccio mcp->mb[8] = size;
6458ec891462SJoe Carnuccio mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
6459ec891462SJoe Carnuccio mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
6460ec891462SJoe Carnuccio mcp->buf_size = size;
6461ec891462SJoe Carnuccio mcp->flags = MBX_DMA_IN;
6462ec891462SJoe Carnuccio mcp->tov = MBX_TOV_SECONDS * 4;
6463ec891462SJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
6464ec891462SJoe Carnuccio
6465ec891462SJoe Carnuccio if (rval != QLA_SUCCESS) {
6466ec891462SJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
6467ec891462SJoe Carnuccio } else {
6468ec891462SJoe Carnuccio ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
6469ec891462SJoe Carnuccio "Done %s.\n", __func__);
6470ec891462SJoe Carnuccio }
6471ec891462SJoe Carnuccio
6472ec891462SJoe Carnuccio dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
6473ec891462SJoe Carnuccio size, DMA_FROM_DEVICE);
6474ec891462SJoe Carnuccio
6475ec891462SJoe Carnuccio return rval;
6476ec891462SJoe Carnuccio }
647715f30a57SQuinn Tran
6478476da8faSBikash Hazarika int
qla26xx_dport_diagnostics_v2(scsi_qla_host_t * vha,struct qla_dport_diag_v2 * dd,mbx_cmd_t * mcp)6479476da8faSBikash Hazarika qla26xx_dport_diagnostics_v2(scsi_qla_host_t *vha,
6480476da8faSBikash Hazarika struct qla_dport_diag_v2 *dd, mbx_cmd_t *mcp)
6481476da8faSBikash Hazarika {
6482476da8faSBikash Hazarika int rval;
6483476da8faSBikash Hazarika dma_addr_t dd_dma;
6484476da8faSBikash Hazarika uint size = sizeof(dd->buf);
6485476da8faSBikash Hazarika uint16_t options = dd->options;
6486476da8faSBikash Hazarika
6487476da8faSBikash Hazarika ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
6488476da8faSBikash Hazarika "Entered %s.\n", __func__);
6489476da8faSBikash Hazarika
6490476da8faSBikash Hazarika dd_dma = dma_map_single(&vha->hw->pdev->dev,
6491476da8faSBikash Hazarika dd->buf, size, DMA_FROM_DEVICE);
6492476da8faSBikash Hazarika if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
6493476da8faSBikash Hazarika ql_log(ql_log_warn, vha, 0x1194,
6494476da8faSBikash Hazarika "Failed to map dma buffer.\n");
6495476da8faSBikash Hazarika return QLA_MEMORY_ALLOC_FAILED;
6496476da8faSBikash Hazarika }
6497476da8faSBikash Hazarika
6498476da8faSBikash Hazarika memset(dd->buf, 0, size);
6499476da8faSBikash Hazarika
6500476da8faSBikash Hazarika mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
6501476da8faSBikash Hazarika mcp->mb[1] = options;
6502476da8faSBikash Hazarika mcp->mb[2] = MSW(LSD(dd_dma));
6503476da8faSBikash Hazarika mcp->mb[3] = LSW(LSD(dd_dma));
6504476da8faSBikash Hazarika mcp->mb[6] = MSW(MSD(dd_dma));
6505476da8faSBikash Hazarika mcp->mb[7] = LSW(MSD(dd_dma));
6506476da8faSBikash Hazarika mcp->mb[8] = size;
6507476da8faSBikash Hazarika mcp->out_mb = MBX_8 | MBX_7 | MBX_6 | MBX_3 | MBX_2 | MBX_1 | MBX_0;
6508476da8faSBikash Hazarika mcp->in_mb = MBX_3 | MBX_2 | MBX_1 | MBX_0;
6509476da8faSBikash Hazarika mcp->buf_size = size;
6510476da8faSBikash Hazarika mcp->flags = MBX_DMA_IN;
6511476da8faSBikash Hazarika mcp->tov = MBX_TOV_SECONDS * 4;
6512476da8faSBikash Hazarika rval = qla2x00_mailbox_command(vha, mcp);
6513476da8faSBikash Hazarika
6514476da8faSBikash Hazarika if (rval != QLA_SUCCESS) {
6515476da8faSBikash Hazarika ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
6516476da8faSBikash Hazarika } else {
6517476da8faSBikash Hazarika ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
6518476da8faSBikash Hazarika "Done %s.\n", __func__);
6519476da8faSBikash Hazarika }
6520476da8faSBikash Hazarika
6521476da8faSBikash Hazarika dma_unmap_single(&vha->hw->pdev->dev, dd_dma, size, DMA_FROM_DEVICE);
6522476da8faSBikash Hazarika
6523476da8faSBikash Hazarika return rval;
6524476da8faSBikash Hazarika }
6525476da8faSBikash Hazarika
qla2x00_async_mb_sp_done(srb_t * sp,int res)65266c18a43eSBart Van Assche static void qla2x00_async_mb_sp_done(srb_t *sp, int res)
652715f30a57SQuinn Tran {
652815f30a57SQuinn Tran sp->u.iocb_cmd.u.mbx.rc = res;
652915f30a57SQuinn Tran
653015f30a57SQuinn Tran complete(&sp->u.iocb_cmd.u.mbx.comp);
653115f30a57SQuinn Tran /* don't free sp here. Let the caller do the free */
653215f30a57SQuinn Tran }
653315f30a57SQuinn Tran
653415f30a57SQuinn Tran /*
653515f30a57SQuinn Tran * This mailbox uses the iocb interface to send MB command.
653615f30a57SQuinn Tran * This allows non-critial (non chip setup) command to go
653715f30a57SQuinn Tran * out in parrallel.
653815f30a57SQuinn Tran */
qla24xx_send_mb_cmd(struct scsi_qla_host * vha,mbx_cmd_t * mcp)653915f30a57SQuinn Tran int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
654015f30a57SQuinn Tran {
654115f30a57SQuinn Tran int rval = QLA_FUNCTION_FAILED;
654215f30a57SQuinn Tran srb_t *sp;
654315f30a57SQuinn Tran struct srb_iocb *c;
654415f30a57SQuinn Tran
654515f30a57SQuinn Tran if (!vha->hw->flags.fw_started)
654615f30a57SQuinn Tran goto done;
654715f30a57SQuinn Tran
654831e6cdbeSSaurav Kashyap /* ref: INIT */
654915f30a57SQuinn Tran sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
655015f30a57SQuinn Tran if (!sp)
655115f30a57SQuinn Tran goto done;
655215f30a57SQuinn Tran
655315f30a57SQuinn Tran c = &sp->u.iocb_cmd;
655415f30a57SQuinn Tran init_completion(&c->u.mbx.comp);
655515f30a57SQuinn Tran
6556d4523bd6SDaniel Wagner sp->type = SRB_MB_IOCB;
6557d4523bd6SDaniel Wagner sp->name = mb_to_str(mcp->mb[0]);
6558d4523bd6SDaniel Wagner qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
6559d4523bd6SDaniel Wagner qla2x00_async_mb_sp_done);
6560e74e7d95SBen Hutchings
6561e74e7d95SBen Hutchings memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
6562e74e7d95SBen Hutchings
656315f30a57SQuinn Tran rval = qla2x00_start_sp(sp);
656415f30a57SQuinn Tran if (rval != QLA_SUCCESS) {
656583548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x1018,
656615f30a57SQuinn Tran "%s: %s Failed submission. %x.\n",
656715f30a57SQuinn Tran __func__, sp->name, rval);
656815f30a57SQuinn Tran goto done_free_sp;
656915f30a57SQuinn Tran }
657015f30a57SQuinn Tran
657183548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n",
657215f30a57SQuinn Tran sp->name, sp->handle);
657315f30a57SQuinn Tran
657415f30a57SQuinn Tran wait_for_completion(&c->u.mbx.comp);
657515f30a57SQuinn Tran memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
657615f30a57SQuinn Tran
657715f30a57SQuinn Tran rval = c->u.mbx.rc;
657815f30a57SQuinn Tran switch (rval) {
657915f30a57SQuinn Tran case QLA_FUNCTION_TIMEOUT:
658083548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n",
658115f30a57SQuinn Tran __func__, sp->name, rval);
658215f30a57SQuinn Tran break;
658315f30a57SQuinn Tran case QLA_SUCCESS:
658483548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
658515f30a57SQuinn Tran __func__, sp->name);
658615f30a57SQuinn Tran break;
658715f30a57SQuinn Tran default:
658883548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
658915f30a57SQuinn Tran __func__, sp->name, rval);
659015f30a57SQuinn Tran break;
659115f30a57SQuinn Tran }
659215f30a57SQuinn Tran
659315f30a57SQuinn Tran done_free_sp:
659431e6cdbeSSaurav Kashyap /* ref: INIT */
659531e6cdbeSSaurav Kashyap kref_put(&sp->cmd_kref, qla2x00_sp_release);
659615f30a57SQuinn Tran done:
659715f30a57SQuinn Tran return rval;
659815f30a57SQuinn Tran }
659915f30a57SQuinn Tran
660015f30a57SQuinn Tran /*
660115f30a57SQuinn Tran * qla24xx_gpdb_wait
660215f30a57SQuinn Tran * NOTE: Do not call this routine from DPC thread
660315f30a57SQuinn Tran */
qla24xx_gpdb_wait(struct scsi_qla_host * vha,fc_port_t * fcport,u8 opt)660415f30a57SQuinn Tran int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
660515f30a57SQuinn Tran {
660615f30a57SQuinn Tran int rval = QLA_FUNCTION_FAILED;
660715f30a57SQuinn Tran dma_addr_t pd_dma;
660815f30a57SQuinn Tran struct port_database_24xx *pd;
660915f30a57SQuinn Tran struct qla_hw_data *ha = vha->hw;
661015f30a57SQuinn Tran mbx_cmd_t mc;
661115f30a57SQuinn Tran
661215f30a57SQuinn Tran if (!vha->hw->flags.fw_started)
661315f30a57SQuinn Tran goto done;
661415f30a57SQuinn Tran
661508eb7f45SThomas Meyer pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
661615f30a57SQuinn Tran if (pd == NULL) {
661783548fe2SQuinn Tran ql_log(ql_log_warn, vha, 0xd047,
661815f30a57SQuinn Tran "Failed to allocate port database structure.\n");
661915f30a57SQuinn Tran goto done_free_sp;
662015f30a57SQuinn Tran }
662115f30a57SQuinn Tran
662215f30a57SQuinn Tran memset(&mc, 0, sizeof(mc));
662315f30a57SQuinn Tran mc.mb[0] = MBC_GET_PORT_DATABASE;
66247ffa5b93SBart Van Assche mc.mb[1] = fcport->loop_id;
662515f30a57SQuinn Tran mc.mb[2] = MSW(pd_dma);
662615f30a57SQuinn Tran mc.mb[3] = LSW(pd_dma);
662715f30a57SQuinn Tran mc.mb[6] = MSW(MSD(pd_dma));
662815f30a57SQuinn Tran mc.mb[7] = LSW(MSD(pd_dma));
66297ffa5b93SBart Van Assche mc.mb[9] = vha->vp_idx;
66307ffa5b93SBart Van Assche mc.mb[10] = opt;
663115f30a57SQuinn Tran
663215f30a57SQuinn Tran rval = qla24xx_send_mb_cmd(vha, &mc);
663315f30a57SQuinn Tran if (rval != QLA_SUCCESS) {
663483548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x1193,
663515f30a57SQuinn Tran "%s: %8phC fail\n", __func__, fcport->port_name);
663615f30a57SQuinn Tran goto done_free_sp;
663715f30a57SQuinn Tran }
663815f30a57SQuinn Tran
663915f30a57SQuinn Tran rval = __qla24xx_parse_gpdb(vha, fcport, pd);
664015f30a57SQuinn Tran
664183548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",
664215f30a57SQuinn Tran __func__, fcport->port_name);
664315f30a57SQuinn Tran
664415f30a57SQuinn Tran done_free_sp:
664515f30a57SQuinn Tran if (pd)
664615f30a57SQuinn Tran dma_pool_free(ha->s_dma_pool, pd, pd_dma);
664715f30a57SQuinn Tran done:
664815f30a57SQuinn Tran return rval;
664915f30a57SQuinn Tran }
665015f30a57SQuinn Tran
__qla24xx_parse_gpdb(struct scsi_qla_host * vha,fc_port_t * fcport,struct port_database_24xx * pd)665115f30a57SQuinn Tran int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
665215f30a57SQuinn Tran struct port_database_24xx *pd)
665315f30a57SQuinn Tran {
665415f30a57SQuinn Tran int rval = QLA_SUCCESS;
665515f30a57SQuinn Tran uint64_t zero = 0;
6656a5d42f4cSDuane Grigsby u8 current_login_state, last_login_state;
6657a5d42f4cSDuane Grigsby
665884ed362aSMichael Hernandez if (NVME_TARGET(vha->hw, fcport)) {
6659a5d42f4cSDuane Grigsby current_login_state = pd->current_login_state >> 4;
6660a5d42f4cSDuane Grigsby last_login_state = pd->last_login_state >> 4;
6661a5d42f4cSDuane Grigsby } else {
6662a5d42f4cSDuane Grigsby current_login_state = pd->current_login_state & 0xf;
6663a5d42f4cSDuane Grigsby last_login_state = pd->last_login_state & 0xf;
6664a5d42f4cSDuane Grigsby }
666515f30a57SQuinn Tran
666615f30a57SQuinn Tran /* Check for logged in state. */
666723c64559SQuinn Tran if (current_login_state != PDS_PRLI_COMPLETE) {
666883548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x119a,
666983548fe2SQuinn Tran "Unable to verify login-state (%x/%x) for loop_id %x.\n",
6670a5d42f4cSDuane Grigsby current_login_state, last_login_state, fcport->loop_id);
667115f30a57SQuinn Tran rval = QLA_FUNCTION_FAILED;
667215f30a57SQuinn Tran goto gpd_error_out;
667315f30a57SQuinn Tran }
667415f30a57SQuinn Tran
667515f30a57SQuinn Tran if (fcport->loop_id == FC_NO_LOOP_ID ||
667615f30a57SQuinn Tran (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
667715f30a57SQuinn Tran memcmp(fcport->port_name, pd->port_name, 8))) {
667815f30a57SQuinn Tran /* We lost the device mid way. */
667915f30a57SQuinn Tran rval = QLA_NOT_LOGGED_IN;
668015f30a57SQuinn Tran goto gpd_error_out;
668115f30a57SQuinn Tran }
668215f30a57SQuinn Tran
668315f30a57SQuinn Tran /* Names are little-endian. */
668415f30a57SQuinn Tran memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
668515f30a57SQuinn Tran memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
668615f30a57SQuinn Tran
668715f30a57SQuinn Tran /* Get port_id of device. */
668815f30a57SQuinn Tran fcport->d_id.b.domain = pd->port_id[0];
668915f30a57SQuinn Tran fcport->d_id.b.area = pd->port_id[1];
669015f30a57SQuinn Tran fcport->d_id.b.al_pa = pd->port_id[2];
669115f30a57SQuinn Tran fcport->d_id.b.rsvd_1 = 0;
669215f30a57SQuinn Tran
66939efea843SQuinn Tran ql_dbg(ql_dbg_disc, vha, 0x2062,
66949efea843SQuinn Tran "%8phC SVC Param w3 %02x%02x",
66959efea843SQuinn Tran fcport->port_name,
66969efea843SQuinn Tran pd->prli_svc_param_word_3[1],
66979efea843SQuinn Tran pd->prli_svc_param_word_3[0]);
66989efea843SQuinn Tran
669984ed362aSMichael Hernandez if (NVME_TARGET(vha->hw, fcport)) {
670084ed362aSMichael Hernandez fcport->port_type = FCT_NVME;
6701a6a6d058SHannes Reinecke if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)
6702a6a6d058SHannes Reinecke fcport->port_type |= FCT_NVME_INITIATOR;
6703a6a6d058SHannes Reinecke if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
6704a6a6d058SHannes Reinecke fcport->port_type |= FCT_NVME_TARGET;
6705a6a6d058SHannes Reinecke if ((pd->prli_svc_param_word_3[0] & BIT_3) == 0)
6706a6a6d058SHannes Reinecke fcport->port_type |= FCT_NVME_DISCOVERY;
6707a5d42f4cSDuane Grigsby } else {
670815f30a57SQuinn Tran /* If not target must be initiator or unknown type. */
670915f30a57SQuinn Tran if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
671015f30a57SQuinn Tran fcport->port_type = FCT_INITIATOR;
671115f30a57SQuinn Tran else
671215f30a57SQuinn Tran fcport->port_type = FCT_TARGET;
6713a5d42f4cSDuane Grigsby }
671415f30a57SQuinn Tran /* Passback COS information. */
671515f30a57SQuinn Tran fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
671615f30a57SQuinn Tran FC_COS_CLASS2 : FC_COS_CLASS3;
671715f30a57SQuinn Tran
671815f30a57SQuinn Tran if (pd->prli_svc_param_word_3[0] & BIT_7) {
671915f30a57SQuinn Tran fcport->flags |= FCF_CONF_COMP_SUPPORTED;
672015f30a57SQuinn Tran fcport->conf_compl_supported = 1;
672115f30a57SQuinn Tran }
672215f30a57SQuinn Tran
672315f30a57SQuinn Tran gpd_error_out:
672415f30a57SQuinn Tran return rval;
672515f30a57SQuinn Tran }
672615f30a57SQuinn Tran
672715f30a57SQuinn Tran /*
672815f30a57SQuinn Tran * qla24xx_gidlist__wait
672915f30a57SQuinn Tran * NOTE: don't call this routine from DPC thread.
673015f30a57SQuinn Tran */
qla24xx_gidlist_wait(struct scsi_qla_host * vha,void * id_list,dma_addr_t id_list_dma,uint16_t * entries)673115f30a57SQuinn Tran int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
673215f30a57SQuinn Tran void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
673315f30a57SQuinn Tran {
673415f30a57SQuinn Tran int rval = QLA_FUNCTION_FAILED;
673515f30a57SQuinn Tran mbx_cmd_t mc;
673615f30a57SQuinn Tran
673715f30a57SQuinn Tran if (!vha->hw->flags.fw_started)
673815f30a57SQuinn Tran goto done;
673915f30a57SQuinn Tran
674015f30a57SQuinn Tran memset(&mc, 0, sizeof(mc));
674115f30a57SQuinn Tran mc.mb[0] = MBC_GET_ID_LIST;
674215f30a57SQuinn Tran mc.mb[2] = MSW(id_list_dma);
674315f30a57SQuinn Tran mc.mb[3] = LSW(id_list_dma);
674415f30a57SQuinn Tran mc.mb[6] = MSW(MSD(id_list_dma));
674515f30a57SQuinn Tran mc.mb[7] = LSW(MSD(id_list_dma));
674615f30a57SQuinn Tran mc.mb[8] = 0;
67477ffa5b93SBart Van Assche mc.mb[9] = vha->vp_idx;
674815f30a57SQuinn Tran
674915f30a57SQuinn Tran rval = qla24xx_send_mb_cmd(vha, &mc);
675015f30a57SQuinn Tran if (rval != QLA_SUCCESS) {
675183548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x119b,
675215f30a57SQuinn Tran "%s: fail\n", __func__);
675315f30a57SQuinn Tran } else {
675415f30a57SQuinn Tran *entries = mc.mb[1];
675583548fe2SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0x119c,
675615f30a57SQuinn Tran "%s: done\n", __func__);
675715f30a57SQuinn Tran }
675815f30a57SQuinn Tran done:
675915f30a57SQuinn Tran return rval;
676015f30a57SQuinn Tran }
6761deeae7a6SDuane Grigsby
qla27xx_set_zio_threshold(scsi_qla_host_t * vha,uint16_t value)6762deeae7a6SDuane Grigsby int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value)
6763deeae7a6SDuane Grigsby {
6764deeae7a6SDuane Grigsby int rval;
6765deeae7a6SDuane Grigsby mbx_cmd_t mc;
6766deeae7a6SDuane Grigsby mbx_cmd_t *mcp = &mc;
6767deeae7a6SDuane Grigsby
6768deeae7a6SDuane Grigsby ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200,
6769deeae7a6SDuane Grigsby "Entered %s\n", __func__);
6770deeae7a6SDuane Grigsby
6771deeae7a6SDuane Grigsby memset(mcp->mb, 0 , sizeof(mcp->mb));
6772deeae7a6SDuane Grigsby mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
67737ffa5b93SBart Van Assche mcp->mb[1] = 1;
67747ffa5b93SBart Van Assche mcp->mb[2] = value;
6775deeae7a6SDuane Grigsby mcp->out_mb = MBX_2 | MBX_1 | MBX_0;
6776deeae7a6SDuane Grigsby mcp->in_mb = MBX_2 | MBX_0;
6777deeae7a6SDuane Grigsby mcp->tov = MBX_TOV_SECONDS;
6778deeae7a6SDuane Grigsby mcp->flags = 0;
6779deeae7a6SDuane Grigsby
6780deeae7a6SDuane Grigsby rval = qla2x00_mailbox_command(vha, mcp);
6781deeae7a6SDuane Grigsby
6782deeae7a6SDuane Grigsby ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n",
6783deeae7a6SDuane Grigsby (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6784deeae7a6SDuane Grigsby
6785deeae7a6SDuane Grigsby return rval;
6786deeae7a6SDuane Grigsby }
6787deeae7a6SDuane Grigsby
qla27xx_get_zio_threshold(scsi_qla_host_t * vha,uint16_t * value)6788deeae7a6SDuane Grigsby int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value)
6789deeae7a6SDuane Grigsby {
6790deeae7a6SDuane Grigsby int rval;
6791deeae7a6SDuane Grigsby mbx_cmd_t mc;
6792deeae7a6SDuane Grigsby mbx_cmd_t *mcp = &mc;
6793deeae7a6SDuane Grigsby
6794deeae7a6SDuane Grigsby ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203,
6795deeae7a6SDuane Grigsby "Entered %s\n", __func__);
6796deeae7a6SDuane Grigsby
6797deeae7a6SDuane Grigsby memset(mcp->mb, 0, sizeof(mcp->mb));
6798deeae7a6SDuane Grigsby mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
67997ffa5b93SBart Van Assche mcp->mb[1] = 0;
6800deeae7a6SDuane Grigsby mcp->out_mb = MBX_1 | MBX_0;
6801deeae7a6SDuane Grigsby mcp->in_mb = MBX_2 | MBX_0;
6802deeae7a6SDuane Grigsby mcp->tov = MBX_TOV_SECONDS;
6803deeae7a6SDuane Grigsby mcp->flags = 0;
6804deeae7a6SDuane Grigsby
6805deeae7a6SDuane Grigsby rval = qla2x00_mailbox_command(vha, mcp);
6806deeae7a6SDuane Grigsby if (rval == QLA_SUCCESS)
6807deeae7a6SDuane Grigsby *value = mc.mb[2];
6808deeae7a6SDuane Grigsby
6809deeae7a6SDuane Grigsby ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n",
6810deeae7a6SDuane Grigsby (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6811deeae7a6SDuane Grigsby
6812deeae7a6SDuane Grigsby return rval;
6813deeae7a6SDuane Grigsby }
6814e4e3a2ceSQuinn Tran
6815e4e3a2ceSQuinn Tran int
qla2x00_read_sfp_dev(struct scsi_qla_host * vha,char * buf,int count)6816e4e3a2ceSQuinn Tran qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count)
6817e4e3a2ceSQuinn Tran {
6818e4e3a2ceSQuinn Tran struct qla_hw_data *ha = vha->hw;
6819e4e3a2ceSQuinn Tran uint16_t iter, addr, offset;
6820e4e3a2ceSQuinn Tran dma_addr_t phys_addr;
6821e4e3a2ceSQuinn Tran int rval, c;
6822e4e3a2ceSQuinn Tran u8 *sfp_data;
6823e4e3a2ceSQuinn Tran
6824e4e3a2ceSQuinn Tran memset(ha->sfp_data, 0, SFP_DEV_SIZE);
6825e4e3a2ceSQuinn Tran addr = 0xa0;
6826e4e3a2ceSQuinn Tran phys_addr = ha->sfp_data_dma;
6827e4e3a2ceSQuinn Tran sfp_data = ha->sfp_data;
6828e4e3a2ceSQuinn Tran offset = c = 0;
6829e4e3a2ceSQuinn Tran
6830e4e3a2ceSQuinn Tran for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) {
6831e4e3a2ceSQuinn Tran if (iter == 4) {
6832e4e3a2ceSQuinn Tran /* Skip to next device address. */
6833e4e3a2ceSQuinn Tran addr = 0xa2;
6834e4e3a2ceSQuinn Tran offset = 0;
6835e4e3a2ceSQuinn Tran }
6836e4e3a2ceSQuinn Tran
6837e4e3a2ceSQuinn Tran rval = qla2x00_read_sfp(vha, phys_addr, sfp_data,
6838e4e3a2ceSQuinn Tran addr, offset, SFP_BLOCK_SIZE, BIT_1);
6839e4e3a2ceSQuinn Tran if (rval != QLA_SUCCESS) {
6840e4e3a2ceSQuinn Tran ql_log(ql_log_warn, vha, 0x706d,
6841e4e3a2ceSQuinn Tran "Unable to read SFP data (%x/%x/%x).\n", rval,
6842e4e3a2ceSQuinn Tran addr, offset);
6843e4e3a2ceSQuinn Tran
6844e4e3a2ceSQuinn Tran return rval;
6845e4e3a2ceSQuinn Tran }
6846e4e3a2ceSQuinn Tran
6847e4e3a2ceSQuinn Tran if (buf && (c < count)) {
6848e4e3a2ceSQuinn Tran u16 sz;
6849e4e3a2ceSQuinn Tran
6850e4e3a2ceSQuinn Tran if ((count - c) >= SFP_BLOCK_SIZE)
6851e4e3a2ceSQuinn Tran sz = SFP_BLOCK_SIZE;
6852e4e3a2ceSQuinn Tran else
6853e4e3a2ceSQuinn Tran sz = count - c;
6854e4e3a2ceSQuinn Tran
6855e4e3a2ceSQuinn Tran memcpy(buf, sfp_data, sz);
6856e4e3a2ceSQuinn Tran buf += SFP_BLOCK_SIZE;
6857e4e3a2ceSQuinn Tran c += sz;
6858e4e3a2ceSQuinn Tran }
6859e4e3a2ceSQuinn Tran phys_addr += SFP_BLOCK_SIZE;
6860e4e3a2ceSQuinn Tran sfp_data += SFP_BLOCK_SIZE;
6861e4e3a2ceSQuinn Tran offset += SFP_BLOCK_SIZE;
6862e4e3a2ceSQuinn Tran }
6863e4e3a2ceSQuinn Tran
6864e4e3a2ceSQuinn Tran return rval;
6865e4e3a2ceSQuinn Tran }
686694d83e36SQuinn Tran
qla24xx_res_count_wait(struct scsi_qla_host * vha,uint16_t * out_mb,int out_mb_sz)686794d83e36SQuinn Tran int qla24xx_res_count_wait(struct scsi_qla_host *vha,
686894d83e36SQuinn Tran uint16_t *out_mb, int out_mb_sz)
686994d83e36SQuinn Tran {
687094d83e36SQuinn Tran int rval = QLA_FUNCTION_FAILED;
687194d83e36SQuinn Tran mbx_cmd_t mc;
687294d83e36SQuinn Tran
687394d83e36SQuinn Tran if (!vha->hw->flags.fw_started)
687494d83e36SQuinn Tran goto done;
687594d83e36SQuinn Tran
687694d83e36SQuinn Tran memset(&mc, 0, sizeof(mc));
687794d83e36SQuinn Tran mc.mb[0] = MBC_GET_RESOURCE_COUNTS;
687894d83e36SQuinn Tran
687994d83e36SQuinn Tran rval = qla24xx_send_mb_cmd(vha, &mc);
688094d83e36SQuinn Tran if (rval != QLA_SUCCESS) {
688194d83e36SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0xffff,
688294d83e36SQuinn Tran "%s: fail\n", __func__);
688394d83e36SQuinn Tran } else {
688494d83e36SQuinn Tran if (out_mb_sz <= SIZEOF_IOCB_MB_REG)
688594d83e36SQuinn Tran memcpy(out_mb, mc.mb, out_mb_sz);
688694d83e36SQuinn Tran else
688794d83e36SQuinn Tran memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);
688894d83e36SQuinn Tran
688994d83e36SQuinn Tran ql_dbg(ql_dbg_mbx, vha, 0xffff,
689094d83e36SQuinn Tran "%s: done\n", __func__);
689194d83e36SQuinn Tran }
689294d83e36SQuinn Tran done:
689394d83e36SQuinn Tran return rval;
689494d83e36SQuinn Tran }
68953f006ac3SMichael Hernandez
qla28xx_secure_flash_update(scsi_qla_host_t * vha,uint16_t opts,uint16_t region,uint32_t len,dma_addr_t sfub_dma_addr,uint32_t sfub_len)68963f006ac3SMichael Hernandez int qla28xx_secure_flash_update(scsi_qla_host_t *vha, uint16_t opts,
68973f006ac3SMichael Hernandez uint16_t region, uint32_t len, dma_addr_t sfub_dma_addr,
68983f006ac3SMichael Hernandez uint32_t sfub_len)
68993f006ac3SMichael Hernandez {
69003f006ac3SMichael Hernandez int rval;
69013f006ac3SMichael Hernandez mbx_cmd_t mc;
69023f006ac3SMichael Hernandez mbx_cmd_t *mcp = &mc;
69033f006ac3SMichael Hernandez
69043f006ac3SMichael Hernandez mcp->mb[0] = MBC_SECURE_FLASH_UPDATE;
69053f006ac3SMichael Hernandez mcp->mb[1] = opts;
69063f006ac3SMichael Hernandez mcp->mb[2] = region;
69073f006ac3SMichael Hernandez mcp->mb[3] = MSW(len);
69083f006ac3SMichael Hernandez mcp->mb[4] = LSW(len);
69093f006ac3SMichael Hernandez mcp->mb[5] = MSW(sfub_dma_addr);
69103f006ac3SMichael Hernandez mcp->mb[6] = LSW(sfub_dma_addr);
69113f006ac3SMichael Hernandez mcp->mb[7] = MSW(MSD(sfub_dma_addr));
69123f006ac3SMichael Hernandez mcp->mb[8] = LSW(MSD(sfub_dma_addr));
69133f006ac3SMichael Hernandez mcp->mb[9] = sfub_len;
69143f006ac3SMichael Hernandez mcp->out_mb =
69153f006ac3SMichael Hernandez MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
69163f006ac3SMichael Hernandez mcp->in_mb = MBX_2|MBX_1|MBX_0;
69173f006ac3SMichael Hernandez mcp->tov = MBX_TOV_SECONDS;
69183f006ac3SMichael Hernandez mcp->flags = 0;
69193f006ac3SMichael Hernandez rval = qla2x00_mailbox_command(vha, mcp);
69203f006ac3SMichael Hernandez
69213f006ac3SMichael Hernandez if (rval != QLA_SUCCESS) {
69223f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s(%ld): failed rval 0x%x, %x %x %x",
69233f006ac3SMichael Hernandez __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1],
69243f006ac3SMichael Hernandez mcp->mb[2]);
69253f006ac3SMichael Hernandez }
69263f006ac3SMichael Hernandez
69273f006ac3SMichael Hernandez return rval;
69283f006ac3SMichael Hernandez }
69293f006ac3SMichael Hernandez
qla2xxx_write_remote_register(scsi_qla_host_t * vha,uint32_t addr,uint32_t data)69303f006ac3SMichael Hernandez int qla2xxx_write_remote_register(scsi_qla_host_t *vha, uint32_t addr,
69313f006ac3SMichael Hernandez uint32_t data)
69323f006ac3SMichael Hernandez {
69333f006ac3SMichael Hernandez int rval;
69343f006ac3SMichael Hernandez mbx_cmd_t mc;
69353f006ac3SMichael Hernandez mbx_cmd_t *mcp = &mc;
69363f006ac3SMichael Hernandez
69373f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
69383f006ac3SMichael Hernandez "Entered %s.\n", __func__);
69393f006ac3SMichael Hernandez
69403f006ac3SMichael Hernandez mcp->mb[0] = MBC_WRITE_REMOTE_REG;
69413f006ac3SMichael Hernandez mcp->mb[1] = LSW(addr);
69423f006ac3SMichael Hernandez mcp->mb[2] = MSW(addr);
69433f006ac3SMichael Hernandez mcp->mb[3] = LSW(data);
69443f006ac3SMichael Hernandez mcp->mb[4] = MSW(data);
69453f006ac3SMichael Hernandez mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
69463f006ac3SMichael Hernandez mcp->in_mb = MBX_1|MBX_0;
69473f006ac3SMichael Hernandez mcp->tov = MBX_TOV_SECONDS;
69483f006ac3SMichael Hernandez mcp->flags = 0;
69493f006ac3SMichael Hernandez rval = qla2x00_mailbox_command(vha, mcp);
69503f006ac3SMichael Hernandez
69513f006ac3SMichael Hernandez if (rval != QLA_SUCCESS) {
69523f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx, vha, 0x10e9,
69533f006ac3SMichael Hernandez "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
69543f006ac3SMichael Hernandez } else {
69553f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
69563f006ac3SMichael Hernandez "Done %s.\n", __func__);
69573f006ac3SMichael Hernandez }
69583f006ac3SMichael Hernandez
69593f006ac3SMichael Hernandez return rval;
69603f006ac3SMichael Hernandez }
69613f006ac3SMichael Hernandez
qla2xxx_read_remote_register(scsi_qla_host_t * vha,uint32_t addr,uint32_t * data)69623f006ac3SMichael Hernandez int qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr,
69633f006ac3SMichael Hernandez uint32_t *data)
69643f006ac3SMichael Hernandez {
69653f006ac3SMichael Hernandez int rval;
69663f006ac3SMichael Hernandez mbx_cmd_t mc;
69673f006ac3SMichael Hernandez mbx_cmd_t *mcp = &mc;
69683f006ac3SMichael Hernandez
69693f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
69703f006ac3SMichael Hernandez "Entered %s.\n", __func__);
69713f006ac3SMichael Hernandez
69723f006ac3SMichael Hernandez mcp->mb[0] = MBC_READ_REMOTE_REG;
69733f006ac3SMichael Hernandez mcp->mb[1] = LSW(addr);
69743f006ac3SMichael Hernandez mcp->mb[2] = MSW(addr);
69753f006ac3SMichael Hernandez mcp->out_mb = MBX_2|MBX_1|MBX_0;
69763f006ac3SMichael Hernandez mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
69773f006ac3SMichael Hernandez mcp->tov = MBX_TOV_SECONDS;
69783f006ac3SMichael Hernandez mcp->flags = 0;
69793f006ac3SMichael Hernandez rval = qla2x00_mailbox_command(vha, mcp);
69803f006ac3SMichael Hernandez
69813f006ac3SMichael Hernandez *data = (uint32_t)((((uint32_t)mcp->mb[4]) << 16) | mcp->mb[3]);
69823f006ac3SMichael Hernandez
69833f006ac3SMichael Hernandez if (rval != QLA_SUCCESS) {
69843f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx, vha, 0x10e9,
69853f006ac3SMichael Hernandez "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
69863f006ac3SMichael Hernandez } else {
69873f006ac3SMichael Hernandez ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
69883f006ac3SMichael Hernandez "Done %s.\n", __func__);
69893f006ac3SMichael Hernandez }
69903f006ac3SMichael Hernandez
69913f006ac3SMichael Hernandez return rval;
69923f006ac3SMichael Hernandez }
699307553b1eSJoe Carnuccio
699407553b1eSJoe Carnuccio int
ql26xx_led_config(scsi_qla_host_t * vha,uint16_t options,uint16_t * led)699507553b1eSJoe Carnuccio ql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led)
699607553b1eSJoe Carnuccio {
699707553b1eSJoe Carnuccio struct qla_hw_data *ha = vha->hw;
699807553b1eSJoe Carnuccio mbx_cmd_t mc;
699907553b1eSJoe Carnuccio mbx_cmd_t *mcp = &mc;
700007553b1eSJoe Carnuccio int rval;
700107553b1eSJoe Carnuccio
700207553b1eSJoe Carnuccio if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
700307553b1eSJoe Carnuccio return QLA_FUNCTION_FAILED;
700407553b1eSJoe Carnuccio
700507553b1eSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x7070, "Entered %s (options=%x).\n",
700607553b1eSJoe Carnuccio __func__, options);
700707553b1eSJoe Carnuccio
700807553b1eSJoe Carnuccio mcp->mb[0] = MBC_SET_GET_FC_LED_CONFIG;
700907553b1eSJoe Carnuccio mcp->mb[1] = options;
701007553b1eSJoe Carnuccio mcp->out_mb = MBX_1|MBX_0;
701107553b1eSJoe Carnuccio mcp->in_mb = MBX_1|MBX_0;
701207553b1eSJoe Carnuccio if (options & BIT_0) {
701307553b1eSJoe Carnuccio if (options & BIT_1) {
701407553b1eSJoe Carnuccio mcp->mb[2] = led[2];
701507553b1eSJoe Carnuccio mcp->out_mb |= MBX_2;
701607553b1eSJoe Carnuccio }
701707553b1eSJoe Carnuccio if (options & BIT_2) {
701807553b1eSJoe Carnuccio mcp->mb[3] = led[0];
701907553b1eSJoe Carnuccio mcp->out_mb |= MBX_3;
702007553b1eSJoe Carnuccio }
702107553b1eSJoe Carnuccio if (options & BIT_3) {
702207553b1eSJoe Carnuccio mcp->mb[4] = led[1];
702307553b1eSJoe Carnuccio mcp->out_mb |= MBX_4;
702407553b1eSJoe Carnuccio }
702507553b1eSJoe Carnuccio } else {
702607553b1eSJoe Carnuccio mcp->in_mb |= MBX_4|MBX_3|MBX_2;
702707553b1eSJoe Carnuccio }
702807553b1eSJoe Carnuccio mcp->tov = MBX_TOV_SECONDS;
702907553b1eSJoe Carnuccio mcp->flags = 0;
703007553b1eSJoe Carnuccio rval = qla2x00_mailbox_command(vha, mcp);
703107553b1eSJoe Carnuccio if (rval) {
703207553b1eSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x7071, "Failed %s %x (mb=%x,%x)\n",
703307553b1eSJoe Carnuccio __func__, rval, mcp->mb[0], mcp->mb[1]);
703407553b1eSJoe Carnuccio return rval;
703507553b1eSJoe Carnuccio }
703607553b1eSJoe Carnuccio
703707553b1eSJoe Carnuccio if (options & BIT_0) {
703807553b1eSJoe Carnuccio ha->beacon_blink_led = 0;
703907553b1eSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x7072, "Done %s\n", __func__);
704007553b1eSJoe Carnuccio } else {
704107553b1eSJoe Carnuccio led[2] = mcp->mb[2];
704207553b1eSJoe Carnuccio led[0] = mcp->mb[3];
704307553b1eSJoe Carnuccio led[1] = mcp->mb[4];
704407553b1eSJoe Carnuccio ql_dbg(ql_dbg_mbx, vha, 0x7073, "Done %s (led=%x,%x,%x)\n",
704507553b1eSJoe Carnuccio __func__, led[0], led[1], led[2]);
704607553b1eSJoe Carnuccio }
704707553b1eSJoe Carnuccio
704807553b1eSJoe Carnuccio return rval;
704907553b1eSJoe Carnuccio }
7050d94d8158SQuinn Tran
7051d94d8158SQuinn Tran /**
7052d94d8158SQuinn Tran * qla_no_op_mb(): This MB is used to check if FW is still alive and
7053d94d8158SQuinn Tran * able to generate an interrupt. Otherwise, a timeout will trigger
7054d94d8158SQuinn Tran * FW dump + reset
7055d94d8158SQuinn Tran * @vha: host adapter pointer
7056d94d8158SQuinn Tran * Return: None
7057d94d8158SQuinn Tran */
qla_no_op_mb(struct scsi_qla_host * vha)7058d94d8158SQuinn Tran void qla_no_op_mb(struct scsi_qla_host *vha)
7059d94d8158SQuinn Tran {
7060d94d8158SQuinn Tran mbx_cmd_t mc;
7061d94d8158SQuinn Tran mbx_cmd_t *mcp = &mc;
7062d94d8158SQuinn Tran int rval;
7063d94d8158SQuinn Tran
7064d94d8158SQuinn Tran memset(&mc, 0, sizeof(mc));
7065d94d8158SQuinn Tran mcp->mb[0] = 0; // noop cmd= 0
7066d94d8158SQuinn Tran mcp->out_mb = MBX_0;
7067d94d8158SQuinn Tran mcp->in_mb = MBX_0;
7068d94d8158SQuinn Tran mcp->tov = 5;
7069d94d8158SQuinn Tran mcp->flags = 0;
7070d94d8158SQuinn Tran rval = qla2x00_mailbox_command(vha, mcp);
7071d94d8158SQuinn Tran
7072d94d8158SQuinn Tran if (rval) {
7073d94d8158SQuinn Tran ql_dbg(ql_dbg_async, vha, 0x7071,
7074d94d8158SQuinn Tran "Failed %s %x\n", __func__, rval);
7075d94d8158SQuinn Tran }
7076d94d8158SQuinn Tran }
70779e1c3206SBikash Hazarika
qla_mailbox_passthru(scsi_qla_host_t * vha,uint16_t * mbx_in,uint16_t * mbx_out)70789e1c3206SBikash Hazarika int qla_mailbox_passthru(scsi_qla_host_t *vha,
70799e1c3206SBikash Hazarika uint16_t *mbx_in, uint16_t *mbx_out)
70809e1c3206SBikash Hazarika {
70819e1c3206SBikash Hazarika mbx_cmd_t mc;
70829e1c3206SBikash Hazarika mbx_cmd_t *mcp = &mc;
70839e1c3206SBikash Hazarika int rval = -EINVAL;
70849e1c3206SBikash Hazarika
70859e1c3206SBikash Hazarika memset(&mc, 0, sizeof(mc));
70869e1c3206SBikash Hazarika /* Receiving all 32 register's contents */
70879e1c3206SBikash Hazarika memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t)));
70889e1c3206SBikash Hazarika
70899e1c3206SBikash Hazarika mcp->out_mb = 0xFFFFFFFF;
70909e1c3206SBikash Hazarika mcp->in_mb = 0xFFFFFFFF;
70919e1c3206SBikash Hazarika
70929e1c3206SBikash Hazarika mcp->tov = MBX_TOV_SECONDS;
70939e1c3206SBikash Hazarika mcp->flags = 0;
70949e1c3206SBikash Hazarika mcp->bufp = NULL;
70959e1c3206SBikash Hazarika
70969e1c3206SBikash Hazarika rval = qla2x00_mailbox_command(vha, mcp);
70979e1c3206SBikash Hazarika
70989e1c3206SBikash Hazarika if (rval != QLA_SUCCESS) {
70999e1c3206SBikash Hazarika ql_dbg(ql_dbg_mbx, vha, 0xf0a2,
71009e1c3206SBikash Hazarika "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
71019e1c3206SBikash Hazarika } else {
71029e1c3206SBikash Hazarika ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n",
71039e1c3206SBikash Hazarika __func__);
71049e1c3206SBikash Hazarika /* passing all 32 register's contents */
71059e1c3206SBikash Hazarika memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t));
71069e1c3206SBikash Hazarika }
71079e1c3206SBikash Hazarika
71089e1c3206SBikash Hazarika return rval;
71099e1c3206SBikash Hazarika }
7110