xref: /openbmc/linux/drivers/scsi/qla2xxx/qla_mbx.c (revision 46eeaa11bdd1bc9e077bdf741d32ca7235d263c6)
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 = &reg->isp82.mailbox_in[0];
2237ec0effdSAtul Deshmukh 	else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
2247ffa5b93SBart Van Assche 		optr = &reg->isp24.mailbox0;
2251c7c6357SAndrew Vasquez 	else
2267ffa5b93SBart Van Assche 		optr = MAILBOX_REG(ha, &reg->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, &reg->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(&reg->isp82.hint, HINT_MBX_INT_PENDING);
26932a13df2SHimanshu Madhani 		else if (IS_FWI2_CAPABLE(ha))
27004474d3aSBart Van Assche 			wrt_reg_dword(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
2711c7c6357SAndrew Vasquez 		else
27204474d3aSBart Van Assche 			wrt_reg_word(&reg->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(&reg->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(&reg->isp82.hint, HINT_MBX_INT_PENDING);
328a9083016SGiridhar Malavali 		} else if (IS_FWI2_CAPABLE(ha))
32904474d3aSBart Van Assche 			wrt_reg_dword(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
3301c7c6357SAndrew Vasquez 		else
33104474d3aSBart Van Assche 			wrt_reg_word(&reg->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(&reg->isp24.mailbox0);
42404474d3aSBart Van Assche 			mb[1] = rd_reg_word(&reg->isp24.mailbox1);
42504474d3aSBart Van Assche 			mb[2] = rd_reg_word(&reg->isp24.mailbox2);
42604474d3aSBart Van Assche 			mb[3] = rd_reg_word(&reg->isp24.mailbox3);
42704474d3aSBart Van Assche 			mb[7] = rd_reg_word(&reg->isp24.mailbox7);
42804474d3aSBart Van Assche 			ictrl = rd_reg_dword(&reg->isp24.ictrl);
42904474d3aSBart Van Assche 			host_status = rd_reg_dword(&reg->isp24.host_status);
43004474d3aSBart Van Assche 			hccr = rd_reg_dword(&reg->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, &reg->isp, 0);
44104474d3aSBart Van Assche 			ictrl = rd_reg_word(&reg->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(&reg->isp24.host_status),
58904474d3aSBart Van Assche 			    rd_reg_dword(&reg->isp24.ictrl),
59004474d3aSBart Van Assche 			    rd_reg_dword(&reg->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(&reg->isp.ctrl_status),
59504474d3aSBart Van Assche 			    rd_reg_word(&reg->isp.ictrl),
59604474d3aSBart Van Assche 			    rd_reg_word(&reg->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(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
551904474d3aSBart Van Assche 	wrt_reg_word(&reg->mailbox1, mb[0]);
552004474d3aSBart Van Assche 	wrt_reg_word(&reg->mailbox2, mb[1]);
552104474d3aSBart Van Assche 	wrt_reg_word(&reg->mailbox3, mb[2]);
552204474d3aSBart Van Assche 	wrt_reg_word(&reg->mailbox4, mb[3]);
5523b1d46989SMadhuranath Iyengar 
552404474d3aSBart Van Assche 	wrt_reg_dword(&reg->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(&reg->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(&reg->mailbox0);
553804474d3aSBart Van Assche 				wrt_reg_dword(&reg->hccr,
5539b1d46989SMadhuranath Iyengar 				    HCCRX_CLR_RISC_INT);
554004474d3aSBart Van Assche 				rd_reg_dword(&reg->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