brintos

brintos / linux-shallow public Read only

0
0
Text · 176.7 KiB · 0cd6f3e Raw
7110 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * QLogic Fibre Channel HBA Driver4 * Copyright (c)  2003-2014 QLogic Corporation5 */6#include "qla_def.h"7#include "qla_target.h"8 9#include <linux/delay.h>10#include <linux/gfp.h>11 12#ifdef CONFIG_PPC13#define IS_PPCARCH      true14#else15#define IS_PPCARCH      false16#endif17 18static struct mb_cmd_name {19	uint16_t cmd;20	const char *str;21} mb_str[] = {22	{MBC_GET_PORT_DATABASE,		"GPDB"},23	{MBC_GET_ID_LIST,		"GIDList"},24	{MBC_GET_LINK_PRIV_STATS,	"Stats"},25	{MBC_GET_RESOURCE_COUNTS,	"ResCnt"},26};27 28static const char *mb_to_str(uint16_t cmd)29{30	int i;31	struct mb_cmd_name *e;32 33	for (i = 0; i < ARRAY_SIZE(mb_str); i++) {34		e = mb_str + i;35		if (cmd == e->cmd)36			return e->str;37	}38	return "unknown";39}40 41static struct rom_cmd {42	uint16_t cmd;43} rom_cmds[] = {44	{ MBC_LOAD_RAM },45	{ MBC_EXECUTE_FIRMWARE },46	{ MBC_READ_RAM_WORD },47	{ MBC_MAILBOX_REGISTER_TEST },48	{ MBC_VERIFY_CHECKSUM },49	{ MBC_GET_FIRMWARE_VERSION },50	{ MBC_LOAD_RISC_RAM },51	{ MBC_DUMP_RISC_RAM },52	{ MBC_LOAD_RISC_RAM_EXTENDED },53	{ MBC_DUMP_RISC_RAM_EXTENDED },54	{ MBC_WRITE_RAM_WORD_EXTENDED },55	{ MBC_READ_RAM_EXTENDED },56	{ MBC_GET_RESOURCE_COUNTS },57	{ MBC_SET_FIRMWARE_OPTION },58	{ MBC_MID_INITIALIZE_FIRMWARE },59	{ MBC_GET_FIRMWARE_STATE },60	{ MBC_GET_MEM_OFFLOAD_CNTRL_STAT },61	{ MBC_GET_RETRY_COUNT },62	{ MBC_TRACE_CONTROL },63	{ MBC_INITIALIZE_MULTIQ },64	{ MBC_IOCB_COMMAND_A64 },65	{ MBC_GET_ADAPTER_LOOP_ID },66	{ MBC_READ_SFP },67	{ MBC_SET_RNID_PARAMS },68	{ MBC_GET_RNID_PARAMS },69	{ MBC_GET_SET_ZIO_THRESHOLD },70};71 72static int is_rom_cmd(uint16_t cmd)73{74	int i;75	struct  rom_cmd *wc;76 77	for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {78		wc = rom_cmds + i;79		if (wc->cmd == cmd)80			return 1;81	}82 83	return 0;84}85 86/*87 * qla2x00_mailbox_command88 *	Issue mailbox command and waits for completion.89 *90 * Input:91 *	ha = adapter block pointer.92 *	mcp = driver internal mbx struct pointer.93 *94 * Output:95 *	mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.96 *97 * Returns:98 *	0 : QLA_SUCCESS = cmd performed success99 *	1 : QLA_FUNCTION_FAILED   (error encountered)100 *	6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)101 *102 * Context:103 *	Kernel context.104 */105static int106qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)107{108	int		rval, i;109	unsigned long    flags = 0;110	device_reg_t *reg;111	uint8_t		abort_active, eeh_delay;112	uint8_t		io_lock_on;113	uint16_t	command = 0;114	uint16_t	*iptr;115	__le16 __iomem  *optr;116	uint32_t	cnt;117	uint32_t	mboxes;118	unsigned long	wait_time;119	struct qla_hw_data *ha = vha->hw;120	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);121	u32 chip_reset;122 123 124	ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);125 126	if (ha->pdev->error_state == pci_channel_io_perm_failure) {127		ql_log(ql_log_warn, vha, 0x1001,128		    "PCI channel failed permanently, exiting.\n");129		return QLA_FUNCTION_TIMEOUT;130	}131 132	if (vha->device_flags & DFLG_DEV_FAILED) {133		ql_log(ql_log_warn, vha, 0x1002,134		    "Device in failed state, exiting.\n");135		return QLA_FUNCTION_TIMEOUT;136	}137 138	/* if PCI error, then avoid mbx processing.*/139	if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) &&140	    test_bit(UNLOADING, &base_vha->dpc_flags)) {141		ql_log(ql_log_warn, vha, 0xd04e,142		    "PCI error, exiting.\n");143		return QLA_FUNCTION_TIMEOUT;144	}145	eeh_delay = 0;146	reg = ha->iobase;147	io_lock_on = base_vha->flags.init_done;148 149	rval = QLA_SUCCESS;150	abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);151	chip_reset = ha->chip_reset;152 153	if (ha->flags.pci_channel_io_perm_failure) {154		ql_log(ql_log_warn, vha, 0x1003,155		    "Perm failure on EEH timeout MBX, exiting.\n");156		return QLA_FUNCTION_TIMEOUT;157	}158 159	if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {160		/* Setting Link-Down error */161		mcp->mb[0] = MBS_LINK_DOWN_ERROR;162		ql_log(ql_log_warn, vha, 0x1004,163		    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);164		return QLA_FUNCTION_TIMEOUT;165	}166 167	/* check if ISP abort is active and return cmd with timeout */168	if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||169	      test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||170	      test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&171	      !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) {172		ql_log(ql_log_info, vha, 0x1005,173		    "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",174		    mcp->mb[0]);175		return QLA_FUNCTION_TIMEOUT;176	}177 178	atomic_inc(&ha->num_pend_mbx_stage1);179	/*180	 * Wait for active mailbox commands to finish by waiting at most tov181	 * seconds. This is to serialize actual issuing of mailbox cmds during182	 * non ISP abort time.183	 */184	if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {185		/* Timeout occurred. Return error. */186		ql_log(ql_log_warn, vha, 0xd035,187		    "Cmd access timeout, cmd=0x%x, Exiting.\n",188		    mcp->mb[0]);189		vha->hw_err_cnt++;190		atomic_dec(&ha->num_pend_mbx_stage1);191		return QLA_FUNCTION_TIMEOUT;192	}193	atomic_dec(&ha->num_pend_mbx_stage1);194	if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||195	    ha->flags.eeh_busy) {196		ql_log(ql_log_warn, vha, 0xd035,197		       "Purge mbox: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n",198		       ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]);199		rval = QLA_ABORTED;200		goto premature_exit;201	}202 203 204	/* Save mailbox command for debug */205	ha->mcp = mcp;206 207	ql_dbg(ql_dbg_mbx, vha, 0x1006,208	    "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);209 210	spin_lock_irqsave(&ha->hardware_lock, flags);211 212	if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||213	    ha->flags.mbox_busy) {214		rval = QLA_ABORTED;215		spin_unlock_irqrestore(&ha->hardware_lock, flags);216		goto premature_exit;217	}218	ha->flags.mbox_busy = 1;219 220	/* Load mailbox registers. */221	if (IS_P3P_TYPE(ha))222		optr = &reg->isp82.mailbox_in[0];223	else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))224		optr = &reg->isp24.mailbox0;225	else226		optr = MAILBOX_REG(ha, &reg->isp, 0);227 228	iptr = mcp->mb;229	command = mcp->mb[0];230	mboxes = mcp->out_mb;231 232	ql_dbg(ql_dbg_mbx, vha, 0x1111,233	    "Mailbox registers (OUT):\n");234	for (cnt = 0; cnt < ha->mbx_count; cnt++) {235		if (IS_QLA2200(ha) && cnt == 8)236			optr = MAILBOX_REG(ha, &reg->isp, 8);237		if (mboxes & BIT_0) {238			ql_dbg(ql_dbg_mbx, vha, 0x1112,239			    "mbox[%d]<-0x%04x\n", cnt, *iptr);240			wrt_reg_word(optr, *iptr);241		} else {242			wrt_reg_word(optr, 0);243		}244 245		mboxes >>= 1;246		optr++;247		iptr++;248	}249 250	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,251	    "I/O Address = %p.\n", optr);252 253	/* Issue set host interrupt command to send cmd out. */254	ha->flags.mbox_int = 0;255	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);256 257	/* Unlock mbx registers and wait for interrupt */258	ql_dbg(ql_dbg_mbx, vha, 0x100f,259	    "Going to unlock irq & waiting for interrupts. "260	    "jiffies=%lx.\n", jiffies);261 262	/* Wait for mbx cmd completion until timeout */263	atomic_inc(&ha->num_pend_mbx_stage2);264	if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {265		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);266 267		if (IS_P3P_TYPE(ha))268			wrt_reg_dword(&reg->isp82.hint, HINT_MBX_INT_PENDING);269		else if (IS_FWI2_CAPABLE(ha))270			wrt_reg_dword(&reg->isp24.hccr, HCCRX_SET_HOST_INT);271		else272			wrt_reg_word(&reg->isp.hccr, HCCR_SET_HOST_INT);273		spin_unlock_irqrestore(&ha->hardware_lock, flags);274 275		wait_time = jiffies;276		if (!wait_for_completion_timeout(&ha->mbx_intr_comp,277		    mcp->tov * HZ)) {278			ql_dbg(ql_dbg_mbx, vha, 0x117a,279			    "cmd=%x Timeout.\n", command);280			spin_lock_irqsave(&ha->hardware_lock, flags);281			clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);282			spin_unlock_irqrestore(&ha->hardware_lock, flags);283 284			if (chip_reset != ha->chip_reset) {285				eeh_delay = ha->flags.eeh_busy ? 1 : 0;286 287				spin_lock_irqsave(&ha->hardware_lock, flags);288				ha->flags.mbox_busy = 0;289				spin_unlock_irqrestore(&ha->hardware_lock,290				    flags);291				atomic_dec(&ha->num_pend_mbx_stage2);292				rval = QLA_ABORTED;293				goto premature_exit;294			}295		} else if (ha->flags.purge_mbox ||296		    chip_reset != ha->chip_reset) {297			eeh_delay = ha->flags.eeh_busy ? 1 : 0;298 299			spin_lock_irqsave(&ha->hardware_lock, flags);300			ha->flags.mbox_busy = 0;301			spin_unlock_irqrestore(&ha->hardware_lock, flags);302			atomic_dec(&ha->num_pend_mbx_stage2);303			rval = QLA_ABORTED;304			goto premature_exit;305		}306 307		if (time_after(jiffies, wait_time + 5 * HZ))308			ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",309			    command, jiffies_to_msecs(jiffies - wait_time));310	} else {311		ql_dbg(ql_dbg_mbx, vha, 0x1011,312		    "Cmd=%x Polling Mode.\n", command);313 314		if (IS_P3P_TYPE(ha)) {315			if (rd_reg_dword(&reg->isp82.hint) &316				HINT_MBX_INT_PENDING) {317				ha->flags.mbox_busy = 0;318				spin_unlock_irqrestore(&ha->hardware_lock,319					flags);320				atomic_dec(&ha->num_pend_mbx_stage2);321				ql_dbg(ql_dbg_mbx, vha, 0x1012,322				    "Pending mailbox timeout, exiting.\n");323				vha->hw_err_cnt++;324				rval = QLA_FUNCTION_TIMEOUT;325				goto premature_exit;326			}327			wrt_reg_dword(&reg->isp82.hint, HINT_MBX_INT_PENDING);328		} else if (IS_FWI2_CAPABLE(ha))329			wrt_reg_dword(&reg->isp24.hccr, HCCRX_SET_HOST_INT);330		else331			wrt_reg_word(&reg->isp.hccr, HCCR_SET_HOST_INT);332		spin_unlock_irqrestore(&ha->hardware_lock, flags);333 334		wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */335		while (!ha->flags.mbox_int) {336			if (ha->flags.purge_mbox ||337			    chip_reset != ha->chip_reset) {338				eeh_delay = ha->flags.eeh_busy ? 1 : 0;339 340				spin_lock_irqsave(&ha->hardware_lock, flags);341				ha->flags.mbox_busy = 0;342				spin_unlock_irqrestore(&ha->hardware_lock,343				    flags);344				atomic_dec(&ha->num_pend_mbx_stage2);345				rval = QLA_ABORTED;346				goto premature_exit;347			}348 349			if (time_after(jiffies, wait_time))350				break;351 352			/* Check for pending interrupts. */353			qla2x00_poll(ha->rsp_q_map[0]);354 355			if (!ha->flags.mbox_int &&356			    !(IS_QLA2200(ha) &&357			    command == MBC_LOAD_RISC_RAM_EXTENDED))358				msleep(10);359		} /* while */360		ql_dbg(ql_dbg_mbx, vha, 0x1013,361		    "Waited %d sec.\n",362		    (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));363	}364	atomic_dec(&ha->num_pend_mbx_stage2);365 366	/* Check whether we timed out */367	if (ha->flags.mbox_int) {368		uint16_t *iptr2;369 370		ql_dbg(ql_dbg_mbx, vha, 0x1014,371		    "Cmd=%x completed.\n", command);372 373		/* Got interrupt. Clear the flag. */374		ha->flags.mbox_int = 0;375		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);376 377		if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {378			spin_lock_irqsave(&ha->hardware_lock, flags);379			ha->flags.mbox_busy = 0;380			spin_unlock_irqrestore(&ha->hardware_lock, flags);381 382			/* Setting Link-Down error */383			mcp->mb[0] = MBS_LINK_DOWN_ERROR;384			ha->mcp = NULL;385			rval = QLA_FUNCTION_FAILED;386			ql_log(ql_log_warn, vha, 0xd048,387			    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);388			goto premature_exit;389		}390 391		if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {392			ql_dbg(ql_dbg_mbx, vha, 0x11ff,393			       "mb_out[0] = %#x <> %#x\n", ha->mailbox_out[0],394			       MBS_COMMAND_COMPLETE);395			rval = QLA_FUNCTION_FAILED;396		}397 398		/* Load return mailbox registers. */399		iptr2 = mcp->mb;400		iptr = (uint16_t *)&ha->mailbox_out[0];401		mboxes = mcp->in_mb;402 403		ql_dbg(ql_dbg_mbx, vha, 0x1113,404		    "Mailbox registers (IN):\n");405		for (cnt = 0; cnt < ha->mbx_count; cnt++) {406			if (mboxes & BIT_0) {407				*iptr2 = *iptr;408				ql_dbg(ql_dbg_mbx, vha, 0x1114,409				    "mbox[%d]->0x%04x\n", cnt, *iptr2);410			}411 412			mboxes >>= 1;413			iptr2++;414			iptr++;415		}416	} else {417 418		uint16_t mb[8];419		uint32_t ictrl, host_status, hccr;420		uint16_t        w;421 422		if (IS_FWI2_CAPABLE(ha)) {423			mb[0] = rd_reg_word(&reg->isp24.mailbox0);424			mb[1] = rd_reg_word(&reg->isp24.mailbox1);425			mb[2] = rd_reg_word(&reg->isp24.mailbox2);426			mb[3] = rd_reg_word(&reg->isp24.mailbox3);427			mb[7] = rd_reg_word(&reg->isp24.mailbox7);428			ictrl = rd_reg_dword(&reg->isp24.ictrl);429			host_status = rd_reg_dword(&reg->isp24.host_status);430			hccr = rd_reg_dword(&reg->isp24.hccr);431 432			ql_log(ql_log_warn, vha, 0xd04c,433			    "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "434			    "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",435			    command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],436			    mb[7], host_status, hccr);437			vha->hw_err_cnt++;438 439		} else {440			mb[0] = RD_MAILBOX_REG(ha, &reg->isp, 0);441			ictrl = rd_reg_word(&reg->isp.ictrl);442			ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,443			    "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "444			    "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);445			vha->hw_err_cnt++;446		}447		ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);448 449		/* Capture FW dump only, if PCI device active */450		if (!pci_channel_offline(vha->hw->pdev)) {451			pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);452			if (w == 0xffff || ictrl == 0xffffffff ||453			    (chip_reset != ha->chip_reset)) {454				/* This is special case if there is unload455				 * of driver happening and if PCI device go456				 * into bad state due to PCI error condition457				 * then only PCI ERR flag would be set.458				 * we will do premature exit for above case.459				 */460				spin_lock_irqsave(&ha->hardware_lock, flags);461				ha->flags.mbox_busy = 0;462				spin_unlock_irqrestore(&ha->hardware_lock,463				    flags);464				rval = QLA_FUNCTION_TIMEOUT;465				goto premature_exit;466			}467 468			/* Attempt to capture firmware dump for further469			 * anallysis of the current formware state. we do not470			 * need to do this if we are intentionally generating471			 * a dump472			 */473			if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)474				qla2xxx_dump_fw(vha);475			rval = QLA_FUNCTION_TIMEOUT;476		 }477	}478	spin_lock_irqsave(&ha->hardware_lock, flags);479	ha->flags.mbox_busy = 0;480	spin_unlock_irqrestore(&ha->hardware_lock, flags);481 482	/* Clean up */483	ha->mcp = NULL;484 485	if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {486		ql_dbg(ql_dbg_mbx, vha, 0x101a,487		    "Checking for additional resp interrupt.\n");488 489		/* polling mode for non isp_abort commands. */490		qla2x00_poll(ha->rsp_q_map[0]);491	}492 493	if (rval == QLA_FUNCTION_TIMEOUT &&494	    mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {495		if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||496		    ha->flags.eeh_busy) {497			/* not in dpc. schedule it for dpc to take over. */498			ql_dbg(ql_dbg_mbx, vha, 0x101b,499			    "Timeout, schedule isp_abort_needed.\n");500 501			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&502			    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&503			    !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {504				if (IS_QLA82XX(ha)) {505					ql_dbg(ql_dbg_mbx, vha, 0x112a,506					    "disabling pause transmit on port "507					    "0 & 1.\n");508					qla82xx_wr_32(ha,509					    QLA82XX_CRB_NIU + 0x98,510					    CRB_NIU_XG_PAUSE_CTL_P0|511					    CRB_NIU_XG_PAUSE_CTL_P1);512				}513				ql_log(ql_log_info, base_vha, 0x101c,514				    "Mailbox cmd timeout occurred, cmd=0x%x, "515				    "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "516				    "abort.\n", command, mcp->mb[0],517				    ha->flags.eeh_busy);518				vha->hw_err_cnt++;519				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);520				qla2xxx_wake_dpc(vha);521			}522		} else if (current == ha->dpc_thread) {523			/* call abort directly since we are in the DPC thread */524			ql_dbg(ql_dbg_mbx, vha, 0x101d,525			    "Timeout, calling abort_isp.\n");526 527			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&528			    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&529			    !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {530				if (IS_QLA82XX(ha)) {531					ql_dbg(ql_dbg_mbx, vha, 0x112b,532					    "disabling pause transmit on port "533					    "0 & 1.\n");534					qla82xx_wr_32(ha,535					    QLA82XX_CRB_NIU + 0x98,536					    CRB_NIU_XG_PAUSE_CTL_P0|537					    CRB_NIU_XG_PAUSE_CTL_P1);538				}539				ql_log(ql_log_info, base_vha, 0x101e,540				    "Mailbox cmd timeout occurred, cmd=0x%x, "541				    "mb[0]=0x%x. Scheduling ISP abort ",542				    command, mcp->mb[0]);543				vha->hw_err_cnt++;544				set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);545				clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);546				/* Allow next mbx cmd to come in. */547				complete(&ha->mbx_cmd_comp);548				if (ha->isp_ops->abort_isp(vha) &&549				    !ha->flags.eeh_busy) {550					/* Failed. retry later. */551					set_bit(ISP_ABORT_NEEDED,552					    &vha->dpc_flags);553				}554				clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);555				ql_dbg(ql_dbg_mbx, vha, 0x101f,556				    "Finished abort_isp.\n");557				goto mbx_done;558			}559		}560	}561 562premature_exit:563	/* Allow next mbx cmd to come in. */564	complete(&ha->mbx_cmd_comp);565 566mbx_done:567	if (rval == QLA_ABORTED) {568		ql_log(ql_log_info, vha, 0xd035,569		    "Chip Reset in progress. Purging Mbox cmd=0x%x.\n",570		    mcp->mb[0]);571	} else if (rval) {572		if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {573			pr_warn("%s [%s]-%04x:%ld: **** Failed=%x", QL_MSGHDR,574			    dev_name(&ha->pdev->dev), 0x1020+0x800,575			    vha->host_no, rval);576			mboxes = mcp->in_mb;577			cnt = 4;578			for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1)579				if (mboxes & BIT_0) {580					printk(" mb[%u]=%x", i, mcp->mb[i]);581					cnt--;582				}583			pr_warn(" cmd=%x ****\n", command);584		}585		if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {586			ql_dbg(ql_dbg_mbx, vha, 0x1198,587			    "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",588			    rd_reg_dword(&reg->isp24.host_status),589			    rd_reg_dword(&reg->isp24.ictrl),590			    rd_reg_dword(&reg->isp24.istatus));591		} else {592			ql_dbg(ql_dbg_mbx, vha, 0x1206,593			    "ctrl_status=%#x ictrl=%#x istatus=%#x\n",594			    rd_reg_word(&reg->isp.ctrl_status),595			    rd_reg_word(&reg->isp.ictrl),596			    rd_reg_word(&reg->isp.istatus));597		}598	} else {599		ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);600	}601 602	i = 500;603	while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) {604		/*605		 * The caller of this mailbox encounter pci error.606		 * Hold the thread until PCIE link reset complete to make607		 * sure caller does not unmap dma while recovery is608		 * in progress.609		 */610		msleep(1);611		i--;612	}613	return rval;614}615 616int617qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,618    uint32_t risc_code_size)619{620	int rval;621	struct qla_hw_data *ha = vha->hw;622	mbx_cmd_t mc;623	mbx_cmd_t *mcp = &mc;624 625	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,626	    "Entered %s.\n", __func__);627 628	if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {629		mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;630		mcp->mb[8] = MSW(risc_addr);631		mcp->out_mb = MBX_8|MBX_0;632	} else {633		mcp->mb[0] = MBC_LOAD_RISC_RAM;634		mcp->out_mb = MBX_0;635	}636	mcp->mb[1] = LSW(risc_addr);637	mcp->mb[2] = MSW(req_dma);638	mcp->mb[3] = LSW(req_dma);639	mcp->mb[6] = MSW(MSD(req_dma));640	mcp->mb[7] = LSW(MSD(req_dma));641	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;642	if (IS_FWI2_CAPABLE(ha)) {643		mcp->mb[4] = MSW(risc_code_size);644		mcp->mb[5] = LSW(risc_code_size);645		mcp->out_mb |= MBX_5|MBX_4;646	} else {647		mcp->mb[4] = LSW(risc_code_size);648		mcp->out_mb |= MBX_4;649	}650 651	mcp->in_mb = MBX_1|MBX_0;652	mcp->tov = MBX_TOV_SECONDS;653	mcp->flags = 0;654	rval = qla2x00_mailbox_command(vha, mcp);655 656	if (rval != QLA_SUCCESS) {657		ql_dbg(ql_dbg_mbx, vha, 0x1023,658		    "Failed=%x mb[0]=%x mb[1]=%x.\n",659		    rval, mcp->mb[0], mcp->mb[1]);660		vha->hw_err_cnt++;661	} else {662		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,663		    "Done %s.\n", __func__);664	}665 666	return rval;667}668 669#define	NVME_ENABLE_FLAG	BIT_3670#define	EDIF_HW_SUPPORT		BIT_10671 672/*673 * qla2x00_execute_fw674 *     Start adapter firmware.675 *676 * Input:677 *     ha = adapter block pointer.678 *     TARGET_QUEUE_LOCK must be released.679 *     ADAPTER_STATE_LOCK must be released.680 *681 * Returns:682 *     qla2x00 local function return status code.683 *684 * Context:685 *     Kernel context.686 */687int688qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)689{690	int rval;691	struct qla_hw_data *ha = vha->hw;692	mbx_cmd_t mc;693	mbx_cmd_t *mcp = &mc;694	u8 semaphore = 0;695#define EXE_FW_FORCE_SEMAPHORE BIT_7696	u8 retry = 5;697 698	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,699	    "Entered %s.\n", __func__);700 701again:702	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;703	mcp->out_mb = MBX_0;704	mcp->in_mb = MBX_0;705	if (IS_FWI2_CAPABLE(ha)) {706		mcp->mb[1] = MSW(risc_addr);707		mcp->mb[2] = LSW(risc_addr);708		mcp->mb[3] = 0;709		mcp->mb[4] = 0;710		mcp->mb[11] = 0;711 712		/* Enable BPM? */713		if (ha->flags.lr_detected) {714			mcp->mb[4] = BIT_0;715			if (IS_BPM_RANGE_CAPABLE(ha))716				mcp->mb[4] |=717				    ha->lr_distance << LR_DIST_FW_POS;718		}719 720		if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha)))721			mcp->mb[4] |= NVME_ENABLE_FLAG;722 723		if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {724			struct nvram_81xx *nv = ha->nvram;725			/* set minimum speed if specified in nvram */726			if (nv->min_supported_speed >= 2 &&727			    nv->min_supported_speed <= 5) {728				mcp->mb[4] |= BIT_4;729				mcp->mb[11] |= nv->min_supported_speed & 0xF;730				mcp->out_mb |= MBX_11;731				mcp->in_mb |= BIT_5;732				vha->min_supported_speed =733				    nv->min_supported_speed;734			}735 736			if (IS_PPCARCH)737				mcp->mb[11] |= BIT_4;738		}739 740		if (ha->flags.exlogins_enabled)741			mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;742 743		if (ha->flags.exchoffld_enabled)744			mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;745 746		if (semaphore)747			mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE;748 749		mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;750		mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1;751	} else {752		mcp->mb[1] = LSW(risc_addr);753		mcp->out_mb |= MBX_1;754		if (IS_QLA2322(ha) || IS_QLA6322(ha)) {755			mcp->mb[2] = 0;756			mcp->out_mb |= MBX_2;757		}758	}759 760	mcp->tov = MBX_TOV_SECONDS;761	mcp->flags = 0;762	rval = qla2x00_mailbox_command(vha, mcp);763 764	if (rval != QLA_SUCCESS) {765		if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR &&766		    mcp->mb[1] == 0x27 && retry) {767			semaphore = 1;768			retry--;769			ql_dbg(ql_dbg_async, vha, 0x1026,770			    "Exe FW: force semaphore.\n");771			goto again;772		}773 774		if (retry) {775			retry--;776			ql_dbg(ql_dbg_async, vha, 0x509d,777			    "Exe FW retry: mb[0]=%x retry[%d]\n", mcp->mb[0], retry);778			goto again;779		}780		ql_dbg(ql_dbg_mbx, vha, 0x1026,781		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);782		vha->hw_err_cnt++;783		return rval;784	}785 786	if (!IS_FWI2_CAPABLE(ha))787		goto done;788 789	ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];790	ql_dbg(ql_dbg_mbx, vha, 0x119a,791	    "fw_ability_mask=%x.\n", ha->fw_ability_mask);792	ql_dbg(ql_dbg_mbx, vha, 0x1027, "exchanges=%x.\n", mcp->mb[1]);793	if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {794		ha->max_supported_speed = mcp->mb[2] & (BIT_0|BIT_1);795		ql_dbg(ql_dbg_mbx, vha, 0x119b, "max_supported_speed=%s.\n",796		    ha->max_supported_speed == 0 ? "16Gps" :797		    ha->max_supported_speed == 1 ? "32Gps" :798		    ha->max_supported_speed == 2 ? "64Gps" : "unknown");799		if (vha->min_supported_speed) {800			ha->min_supported_speed = mcp->mb[5] &801			    (BIT_0 | BIT_1 | BIT_2);802			ql_dbg(ql_dbg_mbx, vha, 0x119c,803			    "min_supported_speed=%s.\n",804			    ha->min_supported_speed == 6 ? "64Gps" :805			    ha->min_supported_speed == 5 ? "32Gps" :806			    ha->min_supported_speed == 4 ? "16Gps" :807			    ha->min_supported_speed == 3 ? "8Gps" :808			    ha->min_supported_speed == 2 ? "4Gps" : "unknown");809		}810	}811 812	if (IS_QLA28XX(ha) && (mcp->mb[5] & EDIF_HW_SUPPORT)) {813		ha->flags.edif_hw = 1;814		ql_log(ql_log_info, vha, 0xffff,815		    "%s: edif HW\n", __func__);816	}817 818done:819	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,820	    "Done %s.\n", __func__);821 822	return rval;823}824 825/*826 * qla_get_exlogin_status827 *	Get extended login status828 *	uses the memory offload control/status Mailbox829 *830 * Input:831 *	ha:		adapter state pointer.832 *	fwopt:		firmware options833 *834 * Returns:835 *	qla2x00 local function status836 *837 * Context:838 *	Kernel context.839 */840#define	FETCH_XLOGINS_STAT	0x8841int842qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,843	uint16_t *ex_logins_cnt)844{845	int rval;846	mbx_cmd_t	mc;847	mbx_cmd_t	*mcp = &mc;848 849	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,850	    "Entered %s\n", __func__);851 852	memset(mcp->mb, 0 , sizeof(mcp->mb));853	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;854	mcp->mb[1] = FETCH_XLOGINS_STAT;855	mcp->out_mb = MBX_1|MBX_0;856	mcp->in_mb = MBX_10|MBX_4|MBX_0;857	mcp->tov = MBX_TOV_SECONDS;858	mcp->flags = 0;859 860	rval = qla2x00_mailbox_command(vha, mcp);861	if (rval != QLA_SUCCESS) {862		ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);863	} else {864		*buf_sz = mcp->mb[4];865		*ex_logins_cnt = mcp->mb[10];866 867		ql_log(ql_log_info, vha, 0x1190,868		    "buffer size 0x%x, exchange login count=%d\n",869		    mcp->mb[4], mcp->mb[10]);870 871		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,872		    "Done %s.\n", __func__);873	}874 875	return rval;876}877 878/*879 * qla_set_exlogin_mem_cfg880 *	set extended login memory configuration881 *	Mbx needs to be issues before init_cb is set882 *883 * Input:884 *	ha:		adapter state pointer.885 *	buffer:		buffer pointer886 *	phys_addr:	physical address of buffer887 *	size:		size of buffer888 *	TARGET_QUEUE_LOCK must be released889 *	ADAPTER_STATE_LOCK must be release890 *891 * Returns:892 *	qla2x00 local funxtion status code.893 *894 * Context:895 *	Kernel context.896 */897#define CONFIG_XLOGINS_MEM	0x9898int899qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)900{901	int		rval;902	mbx_cmd_t	mc;903	mbx_cmd_t	*mcp = &mc;904	struct qla_hw_data *ha = vha->hw;905 906	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,907	    "Entered %s.\n", __func__);908 909	memset(mcp->mb, 0 , sizeof(mcp->mb));910	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;911	mcp->mb[1] = CONFIG_XLOGINS_MEM;912	mcp->mb[2] = MSW(phys_addr);913	mcp->mb[3] = LSW(phys_addr);914	mcp->mb[6] = MSW(MSD(phys_addr));915	mcp->mb[7] = LSW(MSD(phys_addr));916	mcp->mb[8] = MSW(ha->exlogin_size);917	mcp->mb[9] = LSW(ha->exlogin_size);918	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;919	mcp->in_mb = MBX_11|MBX_0;920	mcp->tov = MBX_TOV_SECONDS;921	mcp->flags = 0;922	rval = qla2x00_mailbox_command(vha, mcp);923	if (rval != QLA_SUCCESS) {924		ql_dbg(ql_dbg_mbx, vha, 0x111b,925		       "EXlogin Failed=%x. MB0=%x MB11=%x\n",926		       rval, mcp->mb[0], mcp->mb[11]);927	} else {928		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,929		    "Done %s.\n", __func__);930	}931 932	return rval;933}934 935/*936 * qla_get_exchoffld_status937 *	Get exchange offload status938 *	uses the memory offload control/status Mailbox939 *940 * Input:941 *	ha:		adapter state pointer.942 *	fwopt:		firmware options943 *944 * Returns:945 *	qla2x00 local function status946 *947 * Context:948 *	Kernel context.949 */950#define	FETCH_XCHOFFLD_STAT	0x2951int952qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,953	uint16_t *ex_logins_cnt)954{955	int rval;956	mbx_cmd_t	mc;957	mbx_cmd_t	*mcp = &mc;958 959	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,960	    "Entered %s\n", __func__);961 962	memset(mcp->mb, 0 , sizeof(mcp->mb));963	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;964	mcp->mb[1] = FETCH_XCHOFFLD_STAT;965	mcp->out_mb = MBX_1|MBX_0;966	mcp->in_mb = MBX_10|MBX_4|MBX_0;967	mcp->tov = MBX_TOV_SECONDS;968	mcp->flags = 0;969 970	rval = qla2x00_mailbox_command(vha, mcp);971	if (rval != QLA_SUCCESS) {972		ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);973	} else {974		*buf_sz = mcp->mb[4];975		*ex_logins_cnt = mcp->mb[10];976 977		ql_log(ql_log_info, vha, 0x118e,978		    "buffer size 0x%x, exchange offload count=%d\n",979		    mcp->mb[4], mcp->mb[10]);980 981		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,982		    "Done %s.\n", __func__);983	}984 985	return rval;986}987 988/*989 * qla_set_exchoffld_mem_cfg990 *	Set exchange offload memory configuration991 *	Mbx needs to be issues before init_cb is set992 *993 * Input:994 *	ha:		adapter state pointer.995 *	buffer:		buffer pointer996 *	phys_addr:	physical address of buffer997 *	size:		size of buffer998 *	TARGET_QUEUE_LOCK must be released999 *	ADAPTER_STATE_LOCK must be release1000 *1001 * Returns:1002 *	qla2x00 local funxtion status code.1003 *1004 * Context:1005 *	Kernel context.1006 */1007#define CONFIG_XCHOFFLD_MEM	0x31008int1009qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)1010{1011	int		rval;1012	mbx_cmd_t	mc;1013	mbx_cmd_t	*mcp = &mc;1014	struct qla_hw_data *ha = vha->hw;1015 1016	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,1017	    "Entered %s.\n", __func__);1018 1019	memset(mcp->mb, 0 , sizeof(mcp->mb));1020	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;1021	mcp->mb[1] = CONFIG_XCHOFFLD_MEM;1022	mcp->mb[2] = MSW(ha->exchoffld_buf_dma);1023	mcp->mb[3] = LSW(ha->exchoffld_buf_dma);1024	mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));1025	mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));1026	mcp->mb[8] = MSW(ha->exchoffld_size);1027	mcp->mb[9] = LSW(ha->exchoffld_size);1028	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;1029	mcp->in_mb = MBX_11|MBX_0;1030	mcp->tov = MBX_TOV_SECONDS;1031	mcp->flags = 0;1032	rval = qla2x00_mailbox_command(vha, mcp);1033	if (rval != QLA_SUCCESS) {1034		/*EMPTY*/1035		ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);1036	} else {1037		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,1038		    "Done %s.\n", __func__);1039	}1040 1041	return rval;1042}1043 1044/*1045 * qla2x00_get_fw_version1046 *	Get firmware version.1047 *1048 * Input:1049 *	ha:		adapter state pointer.1050 *	major:		pointer for major number.1051 *	minor:		pointer for minor number.1052 *	subminor:	pointer for subminor number.1053 *1054 * Returns:1055 *	qla2x00 local function return status code.1056 *1057 * Context:1058 *	Kernel context.1059 */1060int1061qla2x00_get_fw_version(scsi_qla_host_t *vha)1062{1063	int		rval;1064	mbx_cmd_t	mc;1065	mbx_cmd_t	*mcp = &mc;1066	struct qla_hw_data *ha = vha->hw;1067 1068	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,1069	    "Entered %s.\n", __func__);1070 1071	mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;1072	mcp->out_mb = MBX_0;1073	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;1074	if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))1075		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;1076	if (IS_FWI2_CAPABLE(ha))1077		mcp->in_mb |= MBX_17|MBX_16|MBX_15;1078	if (IS_QLA27XX(ha) || IS_QLA28XX(ha))1079		mcp->in_mb |=1080		    MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|1081		    MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7;1082 1083	mcp->flags = 0;1084	mcp->tov = MBX_TOV_SECONDS;1085	rval = qla2x00_mailbox_command(vha, mcp);1086	if (rval != QLA_SUCCESS)1087		goto failed;1088 1089	/* Return mailbox data. */1090	ha->fw_major_version = mcp->mb[1];1091	ha->fw_minor_version = mcp->mb[2];1092	ha->fw_subminor_version = mcp->mb[3];1093	ha->fw_attributes = mcp->mb[6];1094	if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))1095		ha->fw_memory_size = 0x1FFFF;		/* Defaults to 128KB. */1096	else1097		ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];1098 1099	if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {1100		ha->mpi_version[0] = mcp->mb[10] & 0xff;1101		ha->mpi_version[1] = mcp->mb[11] >> 8;1102		ha->mpi_version[2] = mcp->mb[11] & 0xff;1103		ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];1104		ha->phy_version[0] = mcp->mb[8] & 0xff;1105		ha->phy_version[1] = mcp->mb[9] >> 8;1106		ha->phy_version[2] = mcp->mb[9] & 0xff;1107	}1108 1109	if (IS_FWI2_CAPABLE(ha)) {1110		ha->fw_attributes_h = mcp->mb[15];1111		ha->fw_attributes_ext[0] = mcp->mb[16];1112		ha->fw_attributes_ext[1] = mcp->mb[17];1113		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,1114		    "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",1115		    __func__, mcp->mb[15], mcp->mb[6]);1116		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,1117		    "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",1118		    __func__, mcp->mb[17], mcp->mb[16]);1119 1120		if (ha->fw_attributes_h & 0x4)1121			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,1122			    "%s: Firmware supports Extended Login 0x%x\n",1123			    __func__, ha->fw_attributes_h);1124 1125		if (ha->fw_attributes_h & 0x8)1126			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,1127			    "%s: Firmware supports Exchange Offload 0x%x\n",1128			    __func__, ha->fw_attributes_h);1129 1130		/*1131		 * FW supports nvme and driver load parameter requested nvme.1132		 * BIT 26 of fw_attributes indicates NVMe support.1133		 */1134		if ((ha->fw_attributes_h &1135		    (FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) &&1136			ql2xnvmeenable) {1137			if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST)1138				vha->flags.nvme_first_burst = 1;1139 1140			vha->flags.nvme_enabled = 1;1141			ql_log(ql_log_info, vha, 0xd302,1142			    "%s: FC-NVMe is Enabled (0x%x)\n",1143			     __func__, ha->fw_attributes_h);1144		}1145 1146		/* BIT_13 of Extended FW Attributes informs about NVMe2 support */1147		if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) {1148			ql_log(ql_log_info, vha, 0xd302,1149			       "Firmware supports NVMe2 0x%x\n",1150			       ha->fw_attributes_ext[0]);1151			vha->flags.nvme2_enabled = 1;1152		}1153 1154		if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable &&1155		    (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) {1156			ha->flags.edif_enabled = 1;1157			ql_log(ql_log_info, vha, 0xffff,1158			       "%s: edif is enabled\n", __func__);1159		}1160	}1161 1162	if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {1163		ha->serdes_version[0] = mcp->mb[7] & 0xff;1164		ha->serdes_version[1] = mcp->mb[8] >> 8;1165		ha->serdes_version[2] = mcp->mb[8] & 0xff;1166		ha->mpi_version[0] = mcp->mb[10] & 0xff;1167		ha->mpi_version[1] = mcp->mb[11] >> 8;1168		ha->mpi_version[2] = mcp->mb[11] & 0xff;1169		ha->pep_version[0] = mcp->mb[13] & 0xff;1170		ha->pep_version[1] = mcp->mb[14] >> 8;1171		ha->pep_version[2] = mcp->mb[14] & 0xff;1172		ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];1173		ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];1174		ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];1175		ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];1176		if (IS_QLA28XX(ha)) {1177			if (mcp->mb[16] & BIT_10)1178				ha->flags.secure_fw = 1;1179 1180			ql_log(ql_log_info, vha, 0xffff,1181			    "Secure Flash Update in FW: %s\n",1182			    (ha->flags.secure_fw) ? "Supported" :1183			    "Not Supported");1184		}1185 1186		if (ha->flags.scm_supported_a &&1187		    (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {1188			ha->flags.scm_supported_f = 1;1189			ha->sf_init_cb->flags |= cpu_to_le16(BIT_13);1190		}1191		ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",1192		       (ha->flags.scm_supported_f) ? "Supported" :1193		       "Not Supported");1194 1195		if (vha->flags.nvme2_enabled) {1196			/* set BIT_15 of special feature control block for SLER */1197			ha->sf_init_cb->flags |= cpu_to_le16(BIT_15);1198			/* set BIT_14 of special feature control block for PI CTRL*/1199			ha->sf_init_cb->flags |= cpu_to_le16(BIT_14);1200		}1201	}1202 1203failed:1204	if (rval != QLA_SUCCESS) {1205		/*EMPTY*/1206		ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);1207	} else {1208		/*EMPTY*/1209		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,1210		    "Done %s.\n", __func__);1211	}1212	return rval;1213}1214 1215/*1216 * qla2x00_get_fw_options1217 *	Set firmware options.1218 *1219 * Input:1220 *	ha = adapter block pointer.1221 *	fwopt = pointer for firmware options.1222 *1223 * Returns:1224 *	qla2x00 local function return status code.1225 *1226 * Context:1227 *	Kernel context.1228 */1229int1230qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)1231{1232	int rval;1233	mbx_cmd_t mc;1234	mbx_cmd_t *mcp = &mc;1235 1236	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,1237	    "Entered %s.\n", __func__);1238 1239	mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;1240	mcp->out_mb = MBX_0;1241	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;1242	mcp->tov = MBX_TOV_SECONDS;1243	mcp->flags = 0;1244	rval = qla2x00_mailbox_command(vha, mcp);1245 1246	if (rval != QLA_SUCCESS) {1247		/*EMPTY*/1248		ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);1249	} else {1250		fwopts[0] = mcp->mb[0];1251		fwopts[1] = mcp->mb[1];1252		fwopts[2] = mcp->mb[2];1253		fwopts[3] = mcp->mb[3];1254 1255		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,1256		    "Done %s.\n", __func__);1257	}1258 1259	return rval;1260}1261 1262 1263/*1264 * qla2x00_set_fw_options1265 *	Set firmware options.1266 *1267 * Input:1268 *	ha = adapter block pointer.1269 *	fwopt = pointer for firmware options.1270 *1271 * Returns:1272 *	qla2x00 local function return status code.1273 *1274 * Context:1275 *	Kernel context.1276 */1277int1278qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)1279{1280	int rval;1281	mbx_cmd_t mc;1282	mbx_cmd_t *mcp = &mc;1283 1284	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,1285	    "Entered %s.\n", __func__);1286 1287	mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;1288	mcp->mb[1] = fwopts[1];1289	mcp->mb[2] = fwopts[2];1290	mcp->mb[3] = fwopts[3];1291	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;1292	mcp->in_mb = MBX_0;1293	if (IS_FWI2_CAPABLE(vha->hw)) {1294		mcp->in_mb |= MBX_1;1295		mcp->mb[10] = fwopts[10];1296		mcp->out_mb |= MBX_10;1297	} else {1298		mcp->mb[10] = fwopts[10];1299		mcp->mb[11] = fwopts[11];1300		mcp->mb[12] = 0;	/* Undocumented, but used */1301		mcp->out_mb |= MBX_12|MBX_11|MBX_10;1302	}1303	mcp->tov = MBX_TOV_SECONDS;1304	mcp->flags = 0;1305	rval = qla2x00_mailbox_command(vha, mcp);1306 1307	fwopts[0] = mcp->mb[0];1308 1309	if (rval != QLA_SUCCESS) {1310		/*EMPTY*/1311		ql_dbg(ql_dbg_mbx, vha, 0x1030,1312		    "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);1313	} else {1314		/*EMPTY*/1315		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,1316		    "Done %s.\n", __func__);1317	}1318 1319	return rval;1320}1321 1322/*1323 * qla2x00_mbx_reg_test1324 *	Mailbox register wrap test.1325 *1326 * Input:1327 *	ha = adapter block pointer.1328 *	TARGET_QUEUE_LOCK must be released.1329 *	ADAPTER_STATE_LOCK must be released.1330 *1331 * Returns:1332 *	qla2x00 local function return status code.1333 *1334 * Context:1335 *	Kernel context.1336 */1337int1338qla2x00_mbx_reg_test(scsi_qla_host_t *vha)1339{1340	int rval;1341	mbx_cmd_t mc;1342	mbx_cmd_t *mcp = &mc;1343 1344	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,1345	    "Entered %s.\n", __func__);1346 1347	mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;1348	mcp->mb[1] = 0xAAAA;1349	mcp->mb[2] = 0x5555;1350	mcp->mb[3] = 0xAA55;1351	mcp->mb[4] = 0x55AA;1352	mcp->mb[5] = 0xA5A5;1353	mcp->mb[6] = 0x5A5A;1354	mcp->mb[7] = 0x2525;1355	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;1356	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;1357	mcp->tov = MBX_TOV_SECONDS;1358	mcp->flags = 0;1359	rval = qla2x00_mailbox_command(vha, mcp);1360 1361	if (rval == QLA_SUCCESS) {1362		if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||1363		    mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)1364			rval = QLA_FUNCTION_FAILED;1365		if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||1366		    mcp->mb[7] != 0x2525)1367			rval = QLA_FUNCTION_FAILED;1368	}1369 1370	if (rval != QLA_SUCCESS) {1371		/*EMPTY*/1372		ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);1373		vha->hw_err_cnt++;1374	} else {1375		/*EMPTY*/1376		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,1377		    "Done %s.\n", __func__);1378	}1379 1380	return rval;1381}1382 1383/*1384 * qla2x00_verify_checksum1385 *	Verify firmware checksum.1386 *1387 * Input:1388 *	ha = adapter block pointer.1389 *	TARGET_QUEUE_LOCK must be released.1390 *	ADAPTER_STATE_LOCK must be released.1391 *1392 * Returns:1393 *	qla2x00 local function return status code.1394 *1395 * Context:1396 *	Kernel context.1397 */1398int1399qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)1400{1401	int rval;1402	mbx_cmd_t mc;1403	mbx_cmd_t *mcp = &mc;1404 1405	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,1406	    "Entered %s.\n", __func__);1407 1408	mcp->mb[0] = MBC_VERIFY_CHECKSUM;1409	mcp->out_mb = MBX_0;1410	mcp->in_mb = MBX_0;1411	if (IS_FWI2_CAPABLE(vha->hw)) {1412		mcp->mb[1] = MSW(risc_addr);1413		mcp->mb[2] = LSW(risc_addr);1414		mcp->out_mb |= MBX_2|MBX_1;1415		mcp->in_mb |= MBX_2|MBX_1;1416	} else {1417		mcp->mb[1] = LSW(risc_addr);1418		mcp->out_mb |= MBX_1;1419		mcp->in_mb |= MBX_1;1420	}1421 1422	mcp->tov = MBX_TOV_SECONDS;1423	mcp->flags = 0;1424	rval = qla2x00_mailbox_command(vha, mcp);1425 1426	if (rval != QLA_SUCCESS) {1427		ql_dbg(ql_dbg_mbx, vha, 0x1036,1428		    "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?1429		    (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);1430	} else {1431		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,1432		    "Done %s.\n", __func__);1433	}1434 1435	return rval;1436}1437 1438/*1439 * qla2x00_issue_iocb1440 *	Issue IOCB using mailbox command1441 *1442 * Input:1443 *	ha = adapter state pointer.1444 *	buffer = buffer pointer.1445 *	phys_addr = physical address of buffer.1446 *	size = size of buffer.1447 *	TARGET_QUEUE_LOCK must be released.1448 *	ADAPTER_STATE_LOCK must be released.1449 *1450 * Returns:1451 *	qla2x00 local function return status code.1452 *1453 * Context:1454 *	Kernel context.1455 */1456int1457qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,1458    dma_addr_t phys_addr, size_t size, uint32_t tov)1459{1460	int		rval;1461	mbx_cmd_t	mc;1462	mbx_cmd_t	*mcp = &mc;1463 1464	if (!vha->hw->flags.fw_started)1465		return QLA_INVALID_COMMAND;1466 1467	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,1468	    "Entered %s.\n", __func__);1469 1470	mcp->mb[0] = MBC_IOCB_COMMAND_A64;1471	mcp->mb[1] = 0;1472	mcp->mb[2] = MSW(LSD(phys_addr));1473	mcp->mb[3] = LSW(LSD(phys_addr));1474	mcp->mb[6] = MSW(MSD(phys_addr));1475	mcp->mb[7] = LSW(MSD(phys_addr));1476	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;1477	mcp->in_mb = MBX_1|MBX_0;1478	mcp->tov = tov;1479	mcp->flags = 0;1480	rval = qla2x00_mailbox_command(vha, mcp);1481 1482	if (rval != QLA_SUCCESS) {1483		/*EMPTY*/1484		ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);1485	} else {1486		sts_entry_t *sts_entry = buffer;1487 1488		/* Mask reserved bits. */1489		sts_entry->entry_status &=1490		    IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;1491		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,1492		    "Done %s (status=%x).\n", __func__,1493		    sts_entry->entry_status);1494	}1495 1496	return rval;1497}1498 1499int1500qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,1501    size_t size)1502{1503	return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,1504	    MBX_TOV_SECONDS);1505}1506 1507/*1508 * qla2x00_abort_command1509 *	Abort command aborts a specified IOCB.1510 *1511 * Input:1512 *	ha = adapter block pointer.1513 *	sp = SB structure pointer.1514 *1515 * Returns:1516 *	qla2x00 local function return status code.1517 *1518 * Context:1519 *	Kernel context.1520 */1521int1522qla2x00_abort_command(srb_t *sp)1523{1524	unsigned long   flags = 0;1525	int		rval;1526	uint32_t	handle = 0;1527	mbx_cmd_t	mc;1528	mbx_cmd_t	*mcp = &mc;1529	fc_port_t	*fcport = sp->fcport;1530	scsi_qla_host_t *vha = fcport->vha;1531	struct qla_hw_data *ha = vha->hw;1532	struct req_que *req;1533	struct scsi_cmnd *cmd = GET_CMD_SP(sp);1534 1535	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,1536	    "Entered %s.\n", __func__);1537 1538	if (sp->qpair)1539		req = sp->qpair->req;1540	else1541		req = vha->req;1542 1543	spin_lock_irqsave(&ha->hardware_lock, flags);1544	for (handle = 1; handle < req->num_outstanding_cmds; handle++) {1545		if (req->outstanding_cmds[handle] == sp)1546			break;1547	}1548	spin_unlock_irqrestore(&ha->hardware_lock, flags);1549 1550	if (handle == req->num_outstanding_cmds) {1551		/* command not found */1552		return QLA_FUNCTION_FAILED;1553	}1554 1555	mcp->mb[0] = MBC_ABORT_COMMAND;1556	if (HAS_EXTENDED_IDS(ha))1557		mcp->mb[1] = fcport->loop_id;1558	else1559		mcp->mb[1] = fcport->loop_id << 8;1560	mcp->mb[2] = (uint16_t)handle;1561	mcp->mb[3] = (uint16_t)(handle >> 16);1562	mcp->mb[6] = (uint16_t)cmd->device->lun;1563	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;1564	mcp->in_mb = MBX_0;1565	mcp->tov = MBX_TOV_SECONDS;1566	mcp->flags = 0;1567	rval = qla2x00_mailbox_command(vha, mcp);1568 1569	if (rval != QLA_SUCCESS) {1570		ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);1571	} else {1572		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,1573		    "Done %s.\n", __func__);1574	}1575 1576	return rval;1577}1578 1579int1580qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)1581{1582	int rval, rval2;1583	mbx_cmd_t  mc;1584	mbx_cmd_t  *mcp = &mc;1585	scsi_qla_host_t *vha;1586 1587	vha = fcport->vha;1588 1589	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,1590	    "Entered %s.\n", __func__);1591 1592	mcp->mb[0] = MBC_ABORT_TARGET;1593	mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;1594	if (HAS_EXTENDED_IDS(vha->hw)) {1595		mcp->mb[1] = fcport->loop_id;1596		mcp->mb[10] = 0;1597		mcp->out_mb |= MBX_10;1598	} else {1599		mcp->mb[1] = fcport->loop_id << 8;1600	}1601	mcp->mb[2] = vha->hw->loop_reset_delay;1602	mcp->mb[9] = vha->vp_idx;1603 1604	mcp->in_mb = MBX_0;1605	mcp->tov = MBX_TOV_SECONDS;1606	mcp->flags = 0;1607	rval = qla2x00_mailbox_command(vha, mcp);1608	if (rval != QLA_SUCCESS) {1609		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,1610		    "Failed=%x.\n", rval);1611	}1612 1613	/* Issue marker IOCB. */1614	rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, 0,1615							MK_SYNC_ID);1616	if (rval2 != QLA_SUCCESS) {1617		ql_dbg(ql_dbg_mbx, vha, 0x1040,1618		    "Failed to issue marker IOCB (%x).\n", rval2);1619	} else {1620		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,1621		    "Done %s.\n", __func__);1622	}1623 1624	return rval;1625}1626 1627int1628qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)1629{1630	int rval, rval2;1631	mbx_cmd_t  mc;1632	mbx_cmd_t  *mcp = &mc;1633	scsi_qla_host_t *vha;1634 1635	vha = fcport->vha;1636 1637	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,1638	    "Entered %s.\n", __func__);1639 1640	mcp->mb[0] = MBC_LUN_RESET;1641	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;1642	if (HAS_EXTENDED_IDS(vha->hw))1643		mcp->mb[1] = fcport->loop_id;1644	else1645		mcp->mb[1] = fcport->loop_id << 8;1646	mcp->mb[2] = (u32)l;1647	mcp->mb[3] = 0;1648	mcp->mb[9] = vha->vp_idx;1649 1650	mcp->in_mb = MBX_0;1651	mcp->tov = MBX_TOV_SECONDS;1652	mcp->flags = 0;1653	rval = qla2x00_mailbox_command(vha, mcp);1654	if (rval != QLA_SUCCESS) {1655		ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);1656	}1657 1658	/* Issue marker IOCB. */1659	rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, l,1660								MK_SYNC_ID_LUN);1661	if (rval2 != QLA_SUCCESS) {1662		ql_dbg(ql_dbg_mbx, vha, 0x1044,1663		    "Failed to issue marker IOCB (%x).\n", rval2);1664	} else {1665		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,1666		    "Done %s.\n", __func__);1667	}1668 1669	return rval;1670}1671 1672/*1673 * qla2x00_get_adapter_id1674 *	Get adapter ID and topology.1675 *1676 * Input:1677 *	ha = adapter block pointer.1678 *	id = pointer for loop ID.1679 *	al_pa = pointer for AL_PA.1680 *	area = pointer for area.1681 *	domain = pointer for domain.1682 *	top = pointer for topology.1683 *	TARGET_QUEUE_LOCK must be released.1684 *	ADAPTER_STATE_LOCK must be released.1685 *1686 * Returns:1687 *	qla2x00 local function return status code.1688 *1689 * Context:1690 *	Kernel context.1691 */1692int1693qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,1694    uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)1695{1696	int rval;1697	mbx_cmd_t mc;1698	mbx_cmd_t *mcp = &mc;1699 1700	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,1701	    "Entered %s.\n", __func__);1702 1703	mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;1704	mcp->mb[9] = vha->vp_idx;1705	mcp->out_mb = MBX_9|MBX_0;1706	mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;1707	if (IS_CNA_CAPABLE(vha->hw))1708		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;1709	if (IS_FWI2_CAPABLE(vha->hw))1710		mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;1711	if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw))1712		mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23;1713 1714	mcp->tov = MBX_TOV_SECONDS;1715	mcp->flags = 0;1716	rval = qla2x00_mailbox_command(vha, mcp);1717	if (mcp->mb[0] == MBS_COMMAND_ERROR)1718		rval = QLA_COMMAND_ERROR;1719	else if (mcp->mb[0] == MBS_INVALID_COMMAND)1720		rval = QLA_INVALID_COMMAND;1721 1722	/* Return data. */1723	*id = mcp->mb[1];1724	*al_pa = LSB(mcp->mb[2]);1725	*area = MSB(mcp->mb[2]);1726	*domain	= LSB(mcp->mb[3]);1727	*top = mcp->mb[6];1728	*sw_cap = mcp->mb[7];1729 1730	if (rval != QLA_SUCCESS) {1731		/*EMPTY*/1732		ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);1733	} else {1734		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,1735		    "Done %s.\n", __func__);1736 1737		if (IS_CNA_CAPABLE(vha->hw)) {1738			vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;1739			vha->fcoe_fcf_idx = mcp->mb[10];1740			vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;1741			vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;1742			vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;1743			vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;1744			vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;1745			vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;1746		}1747		/* If FA-WWN supported */1748		if (IS_FAWWN_CAPABLE(vha->hw)) {1749			if (mcp->mb[7] & BIT_14) {1750				vha->port_name[0] = MSB(mcp->mb[16]);1751				vha->port_name[1] = LSB(mcp->mb[16]);1752				vha->port_name[2] = MSB(mcp->mb[17]);1753				vha->port_name[3] = LSB(mcp->mb[17]);1754				vha->port_name[4] = MSB(mcp->mb[18]);1755				vha->port_name[5] = LSB(mcp->mb[18]);1756				vha->port_name[6] = MSB(mcp->mb[19]);1757				vha->port_name[7] = LSB(mcp->mb[19]);1758				fc_host_port_name(vha->host) =1759				    wwn_to_u64(vha->port_name);1760				ql_dbg(ql_dbg_mbx, vha, 0x10ca,1761				    "FA-WWN acquired %016llx\n",1762				    wwn_to_u64(vha->port_name));1763			}1764		}1765 1766		if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {1767			vha->bbcr = mcp->mb[15];1768			if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) {1769				ql_log(ql_log_info, vha, 0x11a4,1770				       "SCM: EDC ELS completed, flags 0x%x\n",1771				       mcp->mb[21]);1772			}1773			if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) {1774				vha->hw->flags.scm_enabled = 1;1775				vha->scm_fabric_connection_flags |=1776				    SCM_FLAG_RDF_COMPLETED;1777				ql_log(ql_log_info, vha, 0x11a5,1778				       "SCM: RDF ELS completed, flags 0x%x\n",1779				       mcp->mb[23]);1780			}1781		}1782	}1783 1784	return rval;1785}1786 1787/*1788 * qla2x00_get_retry_cnt1789 *	Get current firmware login retry count and delay.1790 *1791 * Input:1792 *	ha = adapter block pointer.1793 *	retry_cnt = pointer to login retry count.1794 *	tov = pointer to login timeout value.1795 *1796 * Returns:1797 *	qla2x00 local function return status code.1798 *1799 * Context:1800 *	Kernel context.1801 */1802int1803qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,1804    uint16_t *r_a_tov)1805{1806	int rval;1807	uint16_t ratov;1808	mbx_cmd_t mc;1809	mbx_cmd_t *mcp = &mc;1810 1811	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,1812	    "Entered %s.\n", __func__);1813 1814	mcp->mb[0] = MBC_GET_RETRY_COUNT;1815	mcp->out_mb = MBX_0;1816	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;1817	mcp->tov = MBX_TOV_SECONDS;1818	mcp->flags = 0;1819	rval = qla2x00_mailbox_command(vha, mcp);1820 1821	if (rval != QLA_SUCCESS) {1822		/*EMPTY*/1823		ql_dbg(ql_dbg_mbx, vha, 0x104a,1824		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);1825	} else {1826		/* Convert returned data and check our values. */1827		*r_a_tov = mcp->mb[3] / 2;1828		ratov = (mcp->mb[3]/2) / 10;  /* mb[3] value is in 100ms */1829		if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {1830			/* Update to the larger values */1831			*retry_cnt = (uint8_t)mcp->mb[1];1832			*tov = ratov;1833		}1834 1835		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,1836		    "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);1837	}1838 1839	return rval;1840}1841 1842/*1843 * qla2x00_init_firmware1844 *	Initialize adapter firmware.1845 *1846 * Input:1847 *	ha = adapter block pointer.1848 *	dptr = Initialization control block pointer.1849 *	size = size of initialization control block.1850 *	TARGET_QUEUE_LOCK must be released.1851 *	ADAPTER_STATE_LOCK must be released.1852 *1853 * Returns:1854 *	qla2x00 local function return status code.1855 *1856 * Context:1857 *	Kernel context.1858 */1859int1860qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)1861{1862	int rval;1863	mbx_cmd_t mc;1864	mbx_cmd_t *mcp = &mc;1865	struct qla_hw_data *ha = vha->hw;1866 1867	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,1868	    "Entered %s.\n", __func__);1869 1870	if (IS_P3P_TYPE(ha) && ql2xdbwr)1871		qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,1872			(0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));1873 1874	if (ha->flags.npiv_supported)1875		mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;1876	else1877		mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;1878 1879	mcp->mb[1] = 0;1880	mcp->mb[2] = MSW(ha->init_cb_dma);1881	mcp->mb[3] = LSW(ha->init_cb_dma);1882	mcp->mb[6] = MSW(MSD(ha->init_cb_dma));1883	mcp->mb[7] = LSW(MSD(ha->init_cb_dma));1884	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;1885	if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {1886		mcp->mb[1] = BIT_0;1887		mcp->mb[10] = MSW(ha->ex_init_cb_dma);1888		mcp->mb[11] = LSW(ha->ex_init_cb_dma);1889		mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));1890		mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));1891		mcp->mb[14] = sizeof(*ha->ex_init_cb);1892		mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;1893	}1894 1895	if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) {1896		mcp->mb[1] |= BIT_1;1897		mcp->mb[16] = MSW(ha->sf_init_cb_dma);1898		mcp->mb[17] = LSW(ha->sf_init_cb_dma);1899		mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma));1900		mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma));1901		mcp->mb[15] = sizeof(*ha->sf_init_cb);1902		mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15;1903	}1904 1905	/* 1 and 2 should normally be captured. */1906	mcp->in_mb = MBX_2|MBX_1|MBX_0;1907	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))1908		/* mb3 is additional info about the installed SFP. */1909		mcp->in_mb  |= MBX_3;1910	mcp->buf_size = size;1911	mcp->flags = MBX_DMA_OUT;1912	mcp->tov = MBX_TOV_SECONDS;1913	rval = qla2x00_mailbox_command(vha, mcp);1914 1915	if (rval != QLA_SUCCESS) {1916		/*EMPTY*/1917		ql_dbg(ql_dbg_mbx, vha, 0x104d,1918		    "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x.\n",1919		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);1920		if (ha->init_cb) {1921			ql_dbg(ql_dbg_mbx, vha, 0x104d, "init_cb:\n");1922			ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha,1923			    0x0104d, ha->init_cb, sizeof(*ha->init_cb));1924		}1925		if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {1926			ql_dbg(ql_dbg_mbx, vha, 0x104d, "ex_init_cb:\n");1927			ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha,1928			    0x0104d, ha->ex_init_cb, sizeof(*ha->ex_init_cb));1929		}1930	} else {1931		if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {1932			if (mcp->mb[2] == 6 || mcp->mb[3] == 2)1933				ql_dbg(ql_dbg_mbx, vha, 0x119d,1934				    "Invalid SFP/Validation Failed\n");1935		}1936		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,1937		    "Done %s.\n", __func__);1938	}1939 1940	return rval;1941}1942 1943 1944/*1945 * qla2x00_get_port_database1946 *	Issue normal/enhanced get port database mailbox command1947 *	and copy device name as necessary.1948 *1949 * Input:1950 *	ha = adapter state pointer.1951 *	dev = structure pointer.1952 *	opt = enhanced cmd option byte.1953 *1954 * Returns:1955 *	qla2x00 local function return status code.1956 *1957 * Context:1958 *	Kernel context.1959 */1960int1961qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)1962{1963	int rval;1964	mbx_cmd_t mc;1965	mbx_cmd_t *mcp = &mc;1966	port_database_t *pd;1967	struct port_database_24xx *pd24;1968	dma_addr_t pd_dma;1969	struct qla_hw_data *ha = vha->hw;1970 1971	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,1972	    "Entered %s.\n", __func__);1973 1974	pd24 = NULL;1975	pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);1976	if (pd  == NULL) {1977		ql_log(ql_log_warn, vha, 0x1050,1978		    "Failed to allocate port database structure.\n");1979		fcport->query = 0;1980		return QLA_MEMORY_ALLOC_FAILED;1981	}1982 1983	mcp->mb[0] = MBC_GET_PORT_DATABASE;1984	if (opt != 0 && !IS_FWI2_CAPABLE(ha))1985		mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;1986	mcp->mb[2] = MSW(pd_dma);1987	mcp->mb[3] = LSW(pd_dma);1988	mcp->mb[6] = MSW(MSD(pd_dma));1989	mcp->mb[7] = LSW(MSD(pd_dma));1990	mcp->mb[9] = vha->vp_idx;1991	mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;1992	mcp->in_mb = MBX_0;1993	if (IS_FWI2_CAPABLE(ha)) {1994		mcp->mb[1] = fcport->loop_id;1995		mcp->mb[10] = opt;1996		mcp->out_mb |= MBX_10|MBX_1;1997		mcp->in_mb |= MBX_1;1998	} else if (HAS_EXTENDED_IDS(ha)) {1999		mcp->mb[1] = fcport->loop_id;2000		mcp->mb[10] = opt;2001		mcp->out_mb |= MBX_10|MBX_1;2002	} else {2003		mcp->mb[1] = fcport->loop_id << 8 | opt;2004		mcp->out_mb |= MBX_1;2005	}2006	mcp->buf_size = IS_FWI2_CAPABLE(ha) ?2007	    PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;2008	mcp->flags = MBX_DMA_IN;2009	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);2010	rval = qla2x00_mailbox_command(vha, mcp);2011	if (rval != QLA_SUCCESS)2012		goto gpd_error_out;2013 2014	if (IS_FWI2_CAPABLE(ha)) {2015		uint64_t zero = 0;2016		u8 current_login_state, last_login_state;2017 2018		pd24 = (struct port_database_24xx *) pd;2019 2020		/* Check for logged in state. */2021		if (NVME_TARGET(ha, fcport)) {2022			current_login_state = pd24->current_login_state >> 4;2023			last_login_state = pd24->last_login_state >> 4;2024		} else {2025			current_login_state = pd24->current_login_state & 0xf;2026			last_login_state = pd24->last_login_state & 0xf;2027		}2028		fcport->current_login_state = pd24->current_login_state;2029		fcport->last_login_state = pd24->last_login_state;2030 2031		/* Check for logged in state. */2032		if (current_login_state != PDS_PRLI_COMPLETE &&2033		    last_login_state != PDS_PRLI_COMPLETE) {2034			ql_dbg(ql_dbg_mbx, vha, 0x119a,2035			    "Unable to verify login-state (%x/%x) for loop_id %x.\n",2036			    current_login_state, last_login_state,2037			    fcport->loop_id);2038			rval = QLA_FUNCTION_FAILED;2039 2040			if (!fcport->query)2041				goto gpd_error_out;2042		}2043 2044		if (fcport->loop_id == FC_NO_LOOP_ID ||2045		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&2046		     memcmp(fcport->port_name, pd24->port_name, 8))) {2047			/* We lost the device mid way. */2048			rval = QLA_NOT_LOGGED_IN;2049			goto gpd_error_out;2050		}2051 2052		/* Names are little-endian. */2053		memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);2054		memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);2055 2056		/* Get port_id of device. */2057		fcport->d_id.b.domain = pd24->port_id[0];2058		fcport->d_id.b.area = pd24->port_id[1];2059		fcport->d_id.b.al_pa = pd24->port_id[2];2060		fcport->d_id.b.rsvd_1 = 0;2061 2062		/* If not target must be initiator or unknown type. */2063		if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)2064			fcport->port_type = FCT_INITIATOR;2065		else2066			fcport->port_type = FCT_TARGET;2067 2068		/* Passback COS information. */2069		fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?2070				FC_COS_CLASS2 : FC_COS_CLASS3;2071 2072		if (pd24->prli_svc_param_word_3[0] & BIT_7)2073			fcport->flags |= FCF_CONF_COMP_SUPPORTED;2074	} else {2075		uint64_t zero = 0;2076 2077		/* Check for logged in state. */2078		if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&2079		    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {2080			ql_dbg(ql_dbg_mbx, vha, 0x100a,2081			    "Unable to verify login-state (%x/%x) - "2082			    "portid=%02x%02x%02x.\n", pd->master_state,2083			    pd->slave_state, fcport->d_id.b.domain,2084			    fcport->d_id.b.area, fcport->d_id.b.al_pa);2085			rval = QLA_FUNCTION_FAILED;2086			goto gpd_error_out;2087		}2088 2089		if (fcport->loop_id == FC_NO_LOOP_ID ||2090		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&2091		     memcmp(fcport->port_name, pd->port_name, 8))) {2092			/* We lost the device mid way. */2093			rval = QLA_NOT_LOGGED_IN;2094			goto gpd_error_out;2095		}2096 2097		/* Names are little-endian. */2098		memcpy(fcport->node_name, pd->node_name, WWN_SIZE);2099		memcpy(fcport->port_name, pd->port_name, WWN_SIZE);2100 2101		/* Get port_id of device. */2102		fcport->d_id.b.domain = pd->port_id[0];2103		fcport->d_id.b.area = pd->port_id[3];2104		fcport->d_id.b.al_pa = pd->port_id[2];2105		fcport->d_id.b.rsvd_1 = 0;2106 2107		/* If not target must be initiator or unknown type. */2108		if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)2109			fcport->port_type = FCT_INITIATOR;2110		else2111			fcport->port_type = FCT_TARGET;2112 2113		/* Passback COS information. */2114		fcport->supported_classes = (pd->options & BIT_4) ?2115		    FC_COS_CLASS2 : FC_COS_CLASS3;2116	}2117 2118gpd_error_out:2119	dma_pool_free(ha->s_dma_pool, pd, pd_dma);2120	fcport->query = 0;2121 2122	if (rval != QLA_SUCCESS) {2123		ql_dbg(ql_dbg_mbx, vha, 0x1052,2124		    "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,2125		    mcp->mb[0], mcp->mb[1]);2126	} else {2127		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,2128		    "Done %s.\n", __func__);2129	}2130 2131	return rval;2132}2133 2134int2135qla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle,2136	struct port_database_24xx *pdb)2137{2138	mbx_cmd_t mc;2139	mbx_cmd_t *mcp = &mc;2140	dma_addr_t pdb_dma;2141	int rval;2142 2143	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1115,2144	    "Entered %s.\n", __func__);2145 2146	memset(pdb, 0, sizeof(*pdb));2147 2148	pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb,2149	    sizeof(*pdb), DMA_FROM_DEVICE);2150	if (!pdb_dma) {2151		ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n");2152		return QLA_MEMORY_ALLOC_FAILED;2153	}2154 2155	mcp->mb[0] = MBC_GET_PORT_DATABASE;2156	mcp->mb[1] = nport_handle;2157	mcp->mb[2] = MSW(LSD(pdb_dma));2158	mcp->mb[3] = LSW(LSD(pdb_dma));2159	mcp->mb[6] = MSW(MSD(pdb_dma));2160	mcp->mb[7] = LSW(MSD(pdb_dma));2161	mcp->mb[9] = 0;2162	mcp->mb[10] = 0;2163	mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;2164	mcp->in_mb = MBX_1|MBX_0;2165	mcp->buf_size = sizeof(*pdb);2166	mcp->flags = MBX_DMA_IN;2167	mcp->tov = vha->hw->login_timeout * 2;2168	rval = qla2x00_mailbox_command(vha, mcp);2169 2170	if (rval != QLA_SUCCESS) {2171		ql_dbg(ql_dbg_mbx, vha, 0x111a,2172		    "Failed=%x mb[0]=%x mb[1]=%x.\n",2173		    rval, mcp->mb[0], mcp->mb[1]);2174	} else {2175		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111b,2176		    "Done %s.\n", __func__);2177	}2178 2179	dma_unmap_single(&vha->hw->pdev->dev, pdb_dma,2180	    sizeof(*pdb), DMA_FROM_DEVICE);2181 2182	return rval;2183}2184 2185/*2186 * qla2x00_get_firmware_state2187 *	Get adapter firmware state.2188 *2189 * Input:2190 *	ha = adapter block pointer.2191 *	dptr = pointer for firmware state.2192 *	TARGET_QUEUE_LOCK must be released.2193 *	ADAPTER_STATE_LOCK must be released.2194 *2195 * Returns:2196 *	qla2x00 local function return status code.2197 *2198 * Context:2199 *	Kernel context.2200 */2201int2202qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)2203{2204	int rval;2205	mbx_cmd_t mc;2206	mbx_cmd_t *mcp = &mc;2207	struct qla_hw_data *ha = vha->hw;2208 2209	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,2210	    "Entered %s.\n", __func__);2211 2212	if (!ha->flags.fw_started)2213		return QLA_FUNCTION_FAILED;2214 2215	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;2216	mcp->out_mb = MBX_0;2217	if (IS_FWI2_CAPABLE(vha->hw))2218		mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;2219	else2220		mcp->in_mb = MBX_1|MBX_0;2221	mcp->tov = MBX_TOV_SECONDS;2222	mcp->flags = 0;2223	rval = qla2x00_mailbox_command(vha, mcp);2224 2225	/* Return firmware states. */2226	states[0] = mcp->mb[1];2227	if (IS_FWI2_CAPABLE(vha->hw)) {2228		states[1] = mcp->mb[2];2229		states[2] = mcp->mb[3];  /* SFP info */2230		states[3] = mcp->mb[4];2231		states[4] = mcp->mb[5];2232		states[5] = mcp->mb[6];  /* DPORT status */2233	}2234 2235	if (rval != QLA_SUCCESS) {2236		/*EMPTY*/2237		ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);2238	} else {2239		if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {2240			if (mcp->mb[2] == 6 || mcp->mb[3] == 2)2241				ql_dbg(ql_dbg_mbx, vha, 0x119e,2242				    "Invalid SFP/Validation Failed\n");2243		}2244		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,2245		    "Done %s.\n", __func__);2246	}2247 2248	return rval;2249}2250 2251/*2252 * qla2x00_get_port_name2253 *	Issue get port name mailbox command.2254 *	Returned name is in big endian format.2255 *2256 * Input:2257 *	ha = adapter block pointer.2258 *	loop_id = loop ID of device.2259 *	name = pointer for name.2260 *	TARGET_QUEUE_LOCK must be released.2261 *	ADAPTER_STATE_LOCK must be released.2262 *2263 * Returns:2264 *	qla2x00 local function return status code.2265 *2266 * Context:2267 *	Kernel context.2268 */2269int2270qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,2271    uint8_t opt)2272{2273	int rval;2274	mbx_cmd_t mc;2275	mbx_cmd_t *mcp = &mc;2276 2277	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,2278	    "Entered %s.\n", __func__);2279 2280	mcp->mb[0] = MBC_GET_PORT_NAME;2281	mcp->mb[9] = vha->vp_idx;2282	mcp->out_mb = MBX_9|MBX_1|MBX_0;2283	if (HAS_EXTENDED_IDS(vha->hw)) {2284		mcp->mb[1] = loop_id;2285		mcp->mb[10] = opt;2286		mcp->out_mb |= MBX_10;2287	} else {2288		mcp->mb[1] = loop_id << 8 | opt;2289	}2290 2291	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;2292	mcp->tov = MBX_TOV_SECONDS;2293	mcp->flags = 0;2294	rval = qla2x00_mailbox_command(vha, mcp);2295 2296	if (rval != QLA_SUCCESS) {2297		/*EMPTY*/2298		ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);2299	} else {2300		if (name != NULL) {2301			/* This function returns name in big endian. */2302			name[0] = MSB(mcp->mb[2]);2303			name[1] = LSB(mcp->mb[2]);2304			name[2] = MSB(mcp->mb[3]);2305			name[3] = LSB(mcp->mb[3]);2306			name[4] = MSB(mcp->mb[6]);2307			name[5] = LSB(mcp->mb[6]);2308			name[6] = MSB(mcp->mb[7]);2309			name[7] = LSB(mcp->mb[7]);2310		}2311 2312		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,2313		    "Done %s.\n", __func__);2314	}2315 2316	return rval;2317}2318 2319/*2320 * qla24xx_link_initialization2321 *	Issue link initialization mailbox command.2322 *2323 * Input:2324 *	ha = adapter block pointer.2325 *	TARGET_QUEUE_LOCK must be released.2326 *	ADAPTER_STATE_LOCK must be released.2327 *2328 * Returns:2329 *	qla2x00 local function return status code.2330 *2331 * Context:2332 *	Kernel context.2333 */2334int2335qla24xx_link_initialize(scsi_qla_host_t *vha)2336{2337	int rval;2338	mbx_cmd_t mc;2339	mbx_cmd_t *mcp = &mc;2340 2341	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,2342	    "Entered %s.\n", __func__);2343 2344	if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))2345		return QLA_FUNCTION_FAILED;2346 2347	mcp->mb[0] = MBC_LINK_INITIALIZATION;2348	mcp->mb[1] = BIT_4;2349	if (vha->hw->operating_mode == LOOP)2350		mcp->mb[1] |= BIT_6;2351	else2352		mcp->mb[1] |= BIT_5;2353	mcp->mb[2] = 0;2354	mcp->mb[3] = 0;2355	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;2356	mcp->in_mb = MBX_0;2357	mcp->tov = MBX_TOV_SECONDS;2358	mcp->flags = 0;2359	rval = qla2x00_mailbox_command(vha, mcp);2360 2361	if (rval != QLA_SUCCESS) {2362		ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);2363	} else {2364		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,2365		    "Done %s.\n", __func__);2366	}2367 2368	return rval;2369}2370 2371/*2372 * qla2x00_lip_reset2373 *	Issue LIP reset mailbox command.2374 *2375 * Input:2376 *	ha = adapter block pointer.2377 *	TARGET_QUEUE_LOCK must be released.2378 *	ADAPTER_STATE_LOCK must be released.2379 *2380 * Returns:2381 *	qla2x00 local function return status code.2382 *2383 * Context:2384 *	Kernel context.2385 */2386int2387qla2x00_lip_reset(scsi_qla_host_t *vha)2388{2389	int rval;2390	mbx_cmd_t mc;2391	mbx_cmd_t *mcp = &mc;2392 2393	ql_dbg(ql_dbg_disc, vha, 0x105a,2394	    "Entered %s.\n", __func__);2395 2396	if (IS_CNA_CAPABLE(vha->hw)) {2397		/* Logout across all FCFs. */2398		mcp->mb[0] = MBC_LIP_FULL_LOGIN;2399		mcp->mb[1] = BIT_1;2400		mcp->mb[2] = 0;2401		mcp->out_mb = MBX_2|MBX_1|MBX_0;2402	} else if (IS_FWI2_CAPABLE(vha->hw)) {2403		mcp->mb[0] = MBC_LIP_FULL_LOGIN;2404		mcp->mb[1] = BIT_4;2405		mcp->mb[2] = 0;2406		mcp->mb[3] = vha->hw->loop_reset_delay;2407		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;2408	} else {2409		mcp->mb[0] = MBC_LIP_RESET;2410		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;2411		if (HAS_EXTENDED_IDS(vha->hw)) {2412			mcp->mb[1] = 0x00ff;2413			mcp->mb[10] = 0;2414			mcp->out_mb |= MBX_10;2415		} else {2416			mcp->mb[1] = 0xff00;2417		}2418		mcp->mb[2] = vha->hw->loop_reset_delay;2419		mcp->mb[3] = 0;2420	}2421	mcp->in_mb = MBX_0;2422	mcp->tov = MBX_TOV_SECONDS;2423	mcp->flags = 0;2424	rval = qla2x00_mailbox_command(vha, mcp);2425 2426	if (rval != QLA_SUCCESS) {2427		/*EMPTY*/2428		ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);2429	} else {2430		/*EMPTY*/2431		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,2432		    "Done %s.\n", __func__);2433	}2434 2435	return rval;2436}2437 2438/*2439 * qla2x00_send_sns2440 *	Send SNS command.2441 *2442 * Input:2443 *	ha = adapter block pointer.2444 *	sns = pointer for command.2445 *	cmd_size = command size.2446 *	buf_size = response/command size.2447 *	TARGET_QUEUE_LOCK must be released.2448 *	ADAPTER_STATE_LOCK must be released.2449 *2450 * Returns:2451 *	qla2x00 local function return status code.2452 *2453 * Context:2454 *	Kernel context.2455 */2456int2457qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,2458    uint16_t cmd_size, size_t buf_size)2459{2460	int rval;2461	mbx_cmd_t mc;2462	mbx_cmd_t *mcp = &mc;2463 2464	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,2465	    "Entered %s.\n", __func__);2466 2467	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,2468	    "Retry cnt=%d ratov=%d total tov=%d.\n",2469	    vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);2470 2471	mcp->mb[0] = MBC_SEND_SNS_COMMAND;2472	mcp->mb[1] = cmd_size;2473	mcp->mb[2] = MSW(sns_phys_address);2474	mcp->mb[3] = LSW(sns_phys_address);2475	mcp->mb[6] = MSW(MSD(sns_phys_address));2476	mcp->mb[7] = LSW(MSD(sns_phys_address));2477	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;2478	mcp->in_mb = MBX_0|MBX_1;2479	mcp->buf_size = buf_size;2480	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;2481	mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);2482	rval = qla2x00_mailbox_command(vha, mcp);2483 2484	if (rval != QLA_SUCCESS) {2485		/*EMPTY*/2486		ql_dbg(ql_dbg_mbx, vha, 0x105f,2487		    "Failed=%x mb[0]=%x mb[1]=%x.\n",2488		    rval, mcp->mb[0], mcp->mb[1]);2489	} else {2490		/*EMPTY*/2491		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,2492		    "Done %s.\n", __func__);2493	}2494 2495	return rval;2496}2497 2498int2499qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,2500    uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)2501{2502	int		rval;2503 2504	struct logio_entry_24xx *lg;2505	dma_addr_t	lg_dma;2506	uint32_t	iop[2];2507	struct qla_hw_data *ha = vha->hw;2508	struct req_que *req;2509 2510	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,2511	    "Entered %s.\n", __func__);2512 2513	if (vha->vp_idx && vha->qpair)2514		req = vha->qpair->req;2515	else2516		req = ha->req_q_map[0];2517 2518	lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);2519	if (lg == NULL) {2520		ql_log(ql_log_warn, vha, 0x1062,2521		    "Failed to allocate login IOCB.\n");2522		return QLA_MEMORY_ALLOC_FAILED;2523	}2524 2525	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;2526	lg->entry_count = 1;2527	lg->handle = make_handle(req->id, lg->handle);2528	lg->nport_handle = cpu_to_le16(loop_id);2529	lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);2530	if (opt & BIT_0)2531		lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);2532	if (opt & BIT_1)2533		lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);2534	lg->port_id[0] = al_pa;2535	lg->port_id[1] = area;2536	lg->port_id[2] = domain;2537	lg->vp_index = vha->vp_idx;2538	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,2539	    (ha->r_a_tov / 10 * 2) + 2);2540	if (rval != QLA_SUCCESS) {2541		ql_dbg(ql_dbg_mbx, vha, 0x1063,2542		    "Failed to issue login IOCB (%x).\n", rval);2543	} else if (lg->entry_status != 0) {2544		ql_dbg(ql_dbg_mbx, vha, 0x1064,2545		    "Failed to complete IOCB -- error status (%x).\n",2546		    lg->entry_status);2547		rval = QLA_FUNCTION_FAILED;2548	} else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {2549		iop[0] = le32_to_cpu(lg->io_parameter[0]);2550		iop[1] = le32_to_cpu(lg->io_parameter[1]);2551 2552		ql_dbg(ql_dbg_mbx, vha, 0x1065,2553		    "Failed to complete IOCB -- completion  status (%x) "2554		    "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),2555		    iop[0], iop[1]);2556 2557		switch (iop[0]) {2558		case LSC_SCODE_PORTID_USED:2559			mb[0] = MBS_PORT_ID_USED;2560			mb[1] = LSW(iop[1]);2561			break;2562		case LSC_SCODE_NPORT_USED:2563			mb[0] = MBS_LOOP_ID_USED;2564			break;2565		case LSC_SCODE_NOLINK:2566		case LSC_SCODE_NOIOCB:2567		case LSC_SCODE_NOXCB:2568		case LSC_SCODE_CMD_FAILED:2569		case LSC_SCODE_NOFABRIC:2570		case LSC_SCODE_FW_NOT_READY:2571		case LSC_SCODE_NOT_LOGGED_IN:2572		case LSC_SCODE_NOPCB:2573		case LSC_SCODE_ELS_REJECT:2574		case LSC_SCODE_CMD_PARAM_ERR:2575		case LSC_SCODE_NONPORT:2576		case LSC_SCODE_LOGGED_IN:2577		case LSC_SCODE_NOFLOGI_ACC:2578		default:2579			mb[0] = MBS_COMMAND_ERROR;2580			break;2581		}2582	} else {2583		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,2584		    "Done %s.\n", __func__);2585 2586		iop[0] = le32_to_cpu(lg->io_parameter[0]);2587 2588		mb[0] = MBS_COMMAND_COMPLETE;2589		mb[1] = 0;2590		if (iop[0] & BIT_4) {2591			if (iop[0] & BIT_8)2592				mb[1] |= BIT_1;2593		} else2594			mb[1] = BIT_0;2595 2596		/* Passback COS information. */2597		mb[10] = 0;2598		if (lg->io_parameter[7] || lg->io_parameter[8])2599			mb[10] |= BIT_0;	/* Class 2. */2600		if (lg->io_parameter[9] || lg->io_parameter[10])2601			mb[10] |= BIT_1;	/* Class 3. */2602		if (lg->io_parameter[0] & cpu_to_le32(BIT_7))2603			mb[10] |= BIT_7;	/* Confirmed Completion2604						 * Allowed2605						 */2606	}2607 2608	dma_pool_free(ha->s_dma_pool, lg, lg_dma);2609 2610	return rval;2611}2612 2613/*2614 * qla2x00_login_fabric2615 *	Issue login fabric port mailbox command.2616 *2617 * Input:2618 *	ha = adapter block pointer.2619 *	loop_id = device loop ID.2620 *	domain = device domain.2621 *	area = device area.2622 *	al_pa = device AL_PA.2623 *	status = pointer for return status.2624 *	opt = command options.2625 *	TARGET_QUEUE_LOCK must be released.2626 *	ADAPTER_STATE_LOCK must be released.2627 *2628 * Returns:2629 *	qla2x00 local function return status code.2630 *2631 * Context:2632 *	Kernel context.2633 */2634int2635qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,2636    uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)2637{2638	int rval;2639	mbx_cmd_t mc;2640	mbx_cmd_t *mcp = &mc;2641	struct qla_hw_data *ha = vha->hw;2642 2643	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,2644	    "Entered %s.\n", __func__);2645 2646	mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;2647	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;2648	if (HAS_EXTENDED_IDS(ha)) {2649		mcp->mb[1] = loop_id;2650		mcp->mb[10] = opt;2651		mcp->out_mb |= MBX_10;2652	} else {2653		mcp->mb[1] = (loop_id << 8) | opt;2654	}2655	mcp->mb[2] = domain;2656	mcp->mb[3] = area << 8 | al_pa;2657 2658	mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;2659	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);2660	mcp->flags = 0;2661	rval = qla2x00_mailbox_command(vha, mcp);2662 2663	/* Return mailbox statuses. */2664	if (mb != NULL) {2665		mb[0] = mcp->mb[0];2666		mb[1] = mcp->mb[1];2667		mb[2] = mcp->mb[2];2668		mb[6] = mcp->mb[6];2669		mb[7] = mcp->mb[7];2670		/* COS retrieved from Get-Port-Database mailbox command. */2671		mb[10] = 0;2672	}2673 2674	if (rval != QLA_SUCCESS) {2675		/* RLU tmp code: need to change main mailbox_command function to2676		 * return ok even when the mailbox completion value is not2677		 * SUCCESS. The caller needs to be responsible to interpret2678		 * the return values of this mailbox command if we're not2679		 * to change too much of the existing code.2680		 */2681		if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||2682		    mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||2683		    mcp->mb[0] == 0x4006)2684			rval = QLA_SUCCESS;2685 2686		/*EMPTY*/2687		ql_dbg(ql_dbg_mbx, vha, 0x1068,2688		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",2689		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);2690	} else {2691		/*EMPTY*/2692		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,2693		    "Done %s.\n", __func__);2694	}2695 2696	return rval;2697}2698 2699/*2700 * qla2x00_login_local_device2701 *           Issue login loop port mailbox command.2702 *2703 * Input:2704 *           ha = adapter block pointer.2705 *           loop_id = device loop ID.2706 *           opt = command options.2707 *2708 * Returns:2709 *            Return status code.2710 *2711 * Context:2712 *            Kernel context.2713 *2714 */2715int2716qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,2717    uint16_t *mb_ret, uint8_t opt)2718{2719	int rval;2720	mbx_cmd_t mc;2721	mbx_cmd_t *mcp = &mc;2722	struct qla_hw_data *ha = vha->hw;2723 2724	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,2725	    "Entered %s.\n", __func__);2726 2727	if (IS_FWI2_CAPABLE(ha))2728		return qla24xx_login_fabric(vha, fcport->loop_id,2729		    fcport->d_id.b.domain, fcport->d_id.b.area,2730		    fcport->d_id.b.al_pa, mb_ret, opt);2731 2732	mcp->mb[0] = MBC_LOGIN_LOOP_PORT;2733	if (HAS_EXTENDED_IDS(ha))2734		mcp->mb[1] = fcport->loop_id;2735	else2736		mcp->mb[1] = fcport->loop_id << 8;2737	mcp->mb[2] = opt;2738	mcp->out_mb = MBX_2|MBX_1|MBX_0;2739 	mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;2740	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);2741	mcp->flags = 0;2742	rval = qla2x00_mailbox_command(vha, mcp);2743 2744 	/* Return mailbox statuses. */2745 	if (mb_ret != NULL) {2746 		mb_ret[0] = mcp->mb[0];2747 		mb_ret[1] = mcp->mb[1];2748 		mb_ret[6] = mcp->mb[6];2749 		mb_ret[7] = mcp->mb[7];2750 	}2751 2752	if (rval != QLA_SUCCESS) {2753 		/* AV tmp code: need to change main mailbox_command function to2754 		 * return ok even when the mailbox completion value is not2755 		 * SUCCESS. The caller needs to be responsible to interpret2756 		 * the return values of this mailbox command if we're not2757 		 * to change too much of the existing code.2758 		 */2759 		if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)2760 			rval = QLA_SUCCESS;2761 2762		ql_dbg(ql_dbg_mbx, vha, 0x106b,2763		    "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",2764		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);2765	} else {2766		/*EMPTY*/2767		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,2768		    "Done %s.\n", __func__);2769	}2770 2771	return (rval);2772}2773 2774int2775qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,2776    uint8_t area, uint8_t al_pa)2777{2778	int		rval;2779	struct logio_entry_24xx *lg;2780	dma_addr_t	lg_dma;2781	struct qla_hw_data *ha = vha->hw;2782	struct req_que *req;2783 2784	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,2785	    "Entered %s.\n", __func__);2786 2787	lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);2788	if (lg == NULL) {2789		ql_log(ql_log_warn, vha, 0x106e,2790		    "Failed to allocate logout IOCB.\n");2791		return QLA_MEMORY_ALLOC_FAILED;2792	}2793 2794	req = vha->req;2795	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;2796	lg->entry_count = 1;2797	lg->handle = make_handle(req->id, lg->handle);2798	lg->nport_handle = cpu_to_le16(loop_id);2799	lg->control_flags =2800	    cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|2801		LCF_FREE_NPORT);2802	lg->port_id[0] = al_pa;2803	lg->port_id[1] = area;2804	lg->port_id[2] = domain;2805	lg->vp_index = vha->vp_idx;2806	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,2807	    (ha->r_a_tov / 10 * 2) + 2);2808	if (rval != QLA_SUCCESS) {2809		ql_dbg(ql_dbg_mbx, vha, 0x106f,2810		    "Failed to issue logout IOCB (%x).\n", rval);2811	} else if (lg->entry_status != 0) {2812		ql_dbg(ql_dbg_mbx, vha, 0x1070,2813		    "Failed to complete IOCB -- error status (%x).\n",2814		    lg->entry_status);2815		rval = QLA_FUNCTION_FAILED;2816	} else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {2817		ql_dbg(ql_dbg_mbx, vha, 0x1071,2818		    "Failed to complete IOCB -- completion status (%x) "2819		    "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),2820		    le32_to_cpu(lg->io_parameter[0]),2821		    le32_to_cpu(lg->io_parameter[1]));2822	} else {2823		/*EMPTY*/2824		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,2825		    "Done %s.\n", __func__);2826	}2827 2828	dma_pool_free(ha->s_dma_pool, lg, lg_dma);2829 2830	return rval;2831}2832 2833/*2834 * qla2x00_fabric_logout2835 *	Issue logout fabric port mailbox command.2836 *2837 * Input:2838 *	ha = adapter block pointer.2839 *	loop_id = device loop ID.2840 *	TARGET_QUEUE_LOCK must be released.2841 *	ADAPTER_STATE_LOCK must be released.2842 *2843 * Returns:2844 *	qla2x00 local function return status code.2845 *2846 * Context:2847 *	Kernel context.2848 */2849int2850qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,2851    uint8_t area, uint8_t al_pa)2852{2853	int rval;2854	mbx_cmd_t mc;2855	mbx_cmd_t *mcp = &mc;2856 2857	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,2858	    "Entered %s.\n", __func__);2859 2860	mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;2861	mcp->out_mb = MBX_1|MBX_0;2862	if (HAS_EXTENDED_IDS(vha->hw)) {2863		mcp->mb[1] = loop_id;2864		mcp->mb[10] = 0;2865		mcp->out_mb |= MBX_10;2866	} else {2867		mcp->mb[1] = loop_id << 8;2868	}2869 2870	mcp->in_mb = MBX_1|MBX_0;2871	mcp->tov = MBX_TOV_SECONDS;2872	mcp->flags = 0;2873	rval = qla2x00_mailbox_command(vha, mcp);2874 2875	if (rval != QLA_SUCCESS) {2876		/*EMPTY*/2877		ql_dbg(ql_dbg_mbx, vha, 0x1074,2878		    "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);2879	} else {2880		/*EMPTY*/2881		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,2882		    "Done %s.\n", __func__);2883	}2884 2885	return rval;2886}2887 2888/*2889 * qla2x00_full_login_lip2890 *	Issue full login LIP mailbox command.2891 *2892 * Input:2893 *	ha = adapter block pointer.2894 *	TARGET_QUEUE_LOCK must be released.2895 *	ADAPTER_STATE_LOCK must be released.2896 *2897 * Returns:2898 *	qla2x00 local function return status code.2899 *2900 * Context:2901 *	Kernel context.2902 */2903int2904qla2x00_full_login_lip(scsi_qla_host_t *vha)2905{2906	int rval;2907	mbx_cmd_t mc;2908	mbx_cmd_t *mcp = &mc;2909 2910	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,2911	    "Entered %s.\n", __func__);2912 2913	mcp->mb[0] = MBC_LIP_FULL_LOGIN;2914	mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_4 : 0;2915	mcp->mb[2] = 0;2916	mcp->mb[3] = 0;2917	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;2918	mcp->in_mb = MBX_0;2919	mcp->tov = MBX_TOV_SECONDS;2920	mcp->flags = 0;2921	rval = qla2x00_mailbox_command(vha, mcp);2922 2923	if (rval != QLA_SUCCESS) {2924		/*EMPTY*/2925		ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);2926	} else {2927		/*EMPTY*/2928		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,2929		    "Done %s.\n", __func__);2930	}2931 2932	return rval;2933}2934 2935/*2936 * qla2x00_get_id_list2937 *2938 * Input:2939 *	ha = adapter block pointer.2940 *2941 * Returns:2942 *	qla2x00 local function return status code.2943 *2944 * Context:2945 *	Kernel context.2946 */2947int2948qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,2949    uint16_t *entries)2950{2951	int rval;2952	mbx_cmd_t mc;2953	mbx_cmd_t *mcp = &mc;2954 2955	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,2956	    "Entered %s.\n", __func__);2957 2958	if (id_list == NULL)2959		return QLA_FUNCTION_FAILED;2960 2961	mcp->mb[0] = MBC_GET_ID_LIST;2962	mcp->out_mb = MBX_0;2963	if (IS_FWI2_CAPABLE(vha->hw)) {2964		mcp->mb[2] = MSW(id_list_dma);2965		mcp->mb[3] = LSW(id_list_dma);2966		mcp->mb[6] = MSW(MSD(id_list_dma));2967		mcp->mb[7] = LSW(MSD(id_list_dma));2968		mcp->mb[8] = 0;2969		mcp->mb[9] = vha->vp_idx;2970		mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;2971	} else {2972		mcp->mb[1] = MSW(id_list_dma);2973		mcp->mb[2] = LSW(id_list_dma);2974		mcp->mb[3] = MSW(MSD(id_list_dma));2975		mcp->mb[6] = LSW(MSD(id_list_dma));2976		mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;2977	}2978	mcp->in_mb = MBX_1|MBX_0;2979	mcp->tov = MBX_TOV_SECONDS;2980	mcp->flags = 0;2981	rval = qla2x00_mailbox_command(vha, mcp);2982 2983	if (rval != QLA_SUCCESS) {2984		/*EMPTY*/2985		ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);2986	} else {2987		*entries = mcp->mb[1];2988		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,2989		    "Done %s.\n", __func__);2990	}2991 2992	return rval;2993}2994 2995/*2996 * qla2x00_get_resource_cnts2997 *	Get current firmware resource counts.2998 *2999 * Input:3000 *	ha = adapter block pointer.3001 *3002 * Returns:3003 *	qla2x00 local function return status code.3004 *3005 * Context:3006 *	Kernel context.3007 */3008int3009qla2x00_get_resource_cnts(scsi_qla_host_t *vha)3010{3011	struct qla_hw_data *ha = vha->hw;3012	int rval;3013	mbx_cmd_t mc;3014	mbx_cmd_t *mcp = &mc;3015 3016	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,3017	    "Entered %s.\n", __func__);3018 3019	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;3020	mcp->out_mb = MBX_0;3021	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;3022	if (IS_QLA81XX(ha) || IS_QLA83XX(ha) ||3023	    IS_QLA27XX(ha) || IS_QLA28XX(ha))3024		mcp->in_mb |= MBX_12;3025	mcp->tov = MBX_TOV_SECONDS;3026	mcp->flags = 0;3027	rval = qla2x00_mailbox_command(vha, mcp);3028 3029	if (rval != QLA_SUCCESS) {3030		/*EMPTY*/3031		ql_dbg(ql_dbg_mbx, vha, 0x107d,3032		    "Failed mb[0]=%x.\n", mcp->mb[0]);3033	} else {3034		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,3035		    "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "3036		    "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],3037		    mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],3038		    mcp->mb[11], mcp->mb[12]);3039 3040		ha->orig_fw_tgt_xcb_count =  mcp->mb[1];3041		ha->cur_fw_tgt_xcb_count = mcp->mb[2];3042		ha->cur_fw_xcb_count = mcp->mb[3];3043		ha->orig_fw_xcb_count = mcp->mb[6];3044		ha->cur_fw_iocb_count = mcp->mb[7];3045		ha->orig_fw_iocb_count = mcp->mb[10];3046		if (ha->flags.npiv_supported)3047			ha->max_npiv_vports = mcp->mb[11];3048		if (IS_QLA81XX(ha) || IS_QLA83XX(ha))3049			ha->fw_max_fcf_count = mcp->mb[12];3050	}3051 3052	return (rval);3053}3054 3055/*3056 * qla2x00_get_fcal_position_map3057 *	Get FCAL (LILP) position map using mailbox command3058 *3059 * Input:3060 *	ha = adapter state pointer.3061 *	pos_map = buffer pointer (can be NULL).3062 *3063 * Returns:3064 *	qla2x00 local function return status code.3065 *3066 * Context:3067 *	Kernel context.3068 */3069int3070qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map,3071		u8 *num_entries)3072{3073	int rval;3074	mbx_cmd_t mc;3075	mbx_cmd_t *mcp = &mc;3076	char *pmap;3077	dma_addr_t pmap_dma;3078	struct qla_hw_data *ha = vha->hw;3079 3080	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,3081	    "Entered %s.\n", __func__);3082 3083	pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);3084	if (pmap  == NULL) {3085		ql_log(ql_log_warn, vha, 0x1080,3086		    "Memory alloc failed.\n");3087		return QLA_MEMORY_ALLOC_FAILED;3088	}3089 3090	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;3091	mcp->mb[2] = MSW(pmap_dma);3092	mcp->mb[3] = LSW(pmap_dma);3093	mcp->mb[6] = MSW(MSD(pmap_dma));3094	mcp->mb[7] = LSW(MSD(pmap_dma));3095	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;3096	mcp->in_mb = MBX_1|MBX_0;3097	mcp->buf_size = FCAL_MAP_SIZE;3098	mcp->flags = MBX_DMA_IN;3099	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);3100	rval = qla2x00_mailbox_command(vha, mcp);3101 3102	if (rval == QLA_SUCCESS) {3103		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,3104		    "mb0/mb1=%x/%X FC/AL position map size (%x).\n",3105		    mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);3106		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,3107		    pmap, pmap[0] + 1);3108 3109		if (pos_map)3110			memcpy(pos_map, pmap, FCAL_MAP_SIZE);3111		if (num_entries)3112			*num_entries = pmap[0];3113	}3114	dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);3115 3116	if (rval != QLA_SUCCESS) {3117		ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);3118	} else {3119		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,3120		    "Done %s.\n", __func__);3121	}3122 3123	return rval;3124}3125 3126/*3127 * qla2x00_get_link_status3128 *3129 * Input:3130 *	ha = adapter block pointer.3131 *	loop_id = device loop ID.3132 *	ret_buf = pointer to link status return buffer.3133 *3134 * Returns:3135 *	0 = success.3136 *	BIT_0 = mem alloc error.3137 *	BIT_1 = mailbox error.3138 */3139int3140qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,3141    struct link_statistics *stats, dma_addr_t stats_dma)3142{3143	int rval;3144	mbx_cmd_t mc;3145	mbx_cmd_t *mcp = &mc;3146	uint32_t *iter = (uint32_t *)stats;3147	ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);3148	struct qla_hw_data *ha = vha->hw;3149 3150	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,3151	    "Entered %s.\n", __func__);3152 3153	mcp->mb[0] = MBC_GET_LINK_STATUS;3154	mcp->mb[2] = MSW(LSD(stats_dma));3155	mcp->mb[3] = LSW(LSD(stats_dma));3156	mcp->mb[6] = MSW(MSD(stats_dma));3157	mcp->mb[7] = LSW(MSD(stats_dma));3158	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;3159	mcp->in_mb = MBX_0;3160	if (IS_FWI2_CAPABLE(ha)) {3161		mcp->mb[1] = loop_id;3162		mcp->mb[4] = 0;3163		mcp->mb[10] = 0;3164		mcp->out_mb |= MBX_10|MBX_4|MBX_1;3165		mcp->in_mb |= MBX_1;3166	} else if (HAS_EXTENDED_IDS(ha)) {3167		mcp->mb[1] = loop_id;3168		mcp->mb[10] = 0;3169		mcp->out_mb |= MBX_10|MBX_1;3170	} else {3171		mcp->mb[1] = loop_id << 8;3172		mcp->out_mb |= MBX_1;3173	}3174	mcp->tov = MBX_TOV_SECONDS;3175	mcp->flags = IOCTL_CMD;3176	rval = qla2x00_mailbox_command(vha, mcp);3177 3178	if (rval == QLA_SUCCESS) {3179		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {3180			ql_dbg(ql_dbg_mbx, vha, 0x1085,3181			    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3182			rval = QLA_FUNCTION_FAILED;3183		} else {3184			/* Re-endianize - firmware data is le32. */3185			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,3186			    "Done %s.\n", __func__);3187			for ( ; dwords--; iter++)3188				le32_to_cpus(iter);3189		}3190	} else {3191		/* Failed. */3192		ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);3193	}3194 3195	return rval;3196}3197 3198int3199qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,3200    dma_addr_t stats_dma, uint16_t options)3201{3202	int rval;3203	mbx_cmd_t mc;3204	mbx_cmd_t *mcp = &mc;3205	uint32_t *iter = (uint32_t *)stats;3206	ushort dwords = sizeof(*stats)/sizeof(*iter);3207 3208	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,3209	    "Entered %s.\n", __func__);3210 3211	memset(&mc, 0, sizeof(mc));3212	mc.mb[0] = MBC_GET_LINK_PRIV_STATS;3213	mc.mb[2] = MSW(LSD(stats_dma));3214	mc.mb[3] = LSW(LSD(stats_dma));3215	mc.mb[6] = MSW(MSD(stats_dma));3216	mc.mb[7] = LSW(MSD(stats_dma));3217	mc.mb[8] = dwords;3218	mc.mb[9] = vha->vp_idx;3219	mc.mb[10] = options;3220 3221	rval = qla24xx_send_mb_cmd(vha, &mc);3222 3223	if (rval == QLA_SUCCESS) {3224		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {3225			ql_dbg(ql_dbg_mbx, vha, 0x1089,3226			    "Failed mb[0]=%x.\n", mcp->mb[0]);3227			rval = QLA_FUNCTION_FAILED;3228		} else {3229			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,3230			    "Done %s.\n", __func__);3231			/* Re-endianize - firmware data is le32. */3232			for ( ; dwords--; iter++)3233				le32_to_cpus(iter);3234		}3235	} else {3236		/* Failed. */3237		ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);3238	}3239 3240	return rval;3241}3242 3243int3244qla24xx_abort_command(srb_t *sp)3245{3246	int		rval;3247	unsigned long   flags = 0;3248 3249	struct abort_entry_24xx *abt;3250	dma_addr_t	abt_dma;3251	uint32_t	handle;3252	fc_port_t	*fcport = sp->fcport;3253	struct scsi_qla_host *vha = fcport->vha;3254	struct qla_hw_data *ha = vha->hw;3255	struct req_que *req;3256	struct qla_qpair *qpair = sp->qpair;3257 3258	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,3259	    "Entered %s.\n", __func__);3260 3261	if (sp->qpair)3262		req = sp->qpair->req;3263	else3264		return QLA_ERR_NO_QPAIR;3265 3266	if (ql2xasynctmfenable)3267		return qla24xx_async_abort_command(sp);3268 3269	spin_lock_irqsave(qpair->qp_lock_ptr, flags);3270	for (handle = 1; handle < req->num_outstanding_cmds; handle++) {3271		if (req->outstanding_cmds[handle] == sp)3272			break;3273	}3274	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);3275	if (handle == req->num_outstanding_cmds) {3276		/* Command not found. */3277		return QLA_ERR_NOT_FOUND;3278	}3279 3280	abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);3281	if (abt == NULL) {3282		ql_log(ql_log_warn, vha, 0x108d,3283		    "Failed to allocate abort IOCB.\n");3284		return QLA_MEMORY_ALLOC_FAILED;3285	}3286 3287	abt->entry_type = ABORT_IOCB_TYPE;3288	abt->entry_count = 1;3289	abt->handle = make_handle(req->id, abt->handle);3290	abt->nport_handle = cpu_to_le16(fcport->loop_id);3291	abt->handle_to_abort = make_handle(req->id, handle);3292	abt->port_id[0] = fcport->d_id.b.al_pa;3293	abt->port_id[1] = fcport->d_id.b.area;3294	abt->port_id[2] = fcport->d_id.b.domain;3295	abt->vp_index = fcport->vha->vp_idx;3296 3297	abt->req_que_no = cpu_to_le16(req->id);3298	/* Need to pass original sp */3299	qla_nvme_abort_set_option(abt, sp);3300 3301	rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);3302	if (rval != QLA_SUCCESS) {3303		ql_dbg(ql_dbg_mbx, vha, 0x108e,3304		    "Failed to issue IOCB (%x).\n", rval);3305	} else if (abt->entry_status != 0) {3306		ql_dbg(ql_dbg_mbx, vha, 0x108f,3307		    "Failed to complete IOCB -- error status (%x).\n",3308		    abt->entry_status);3309		rval = QLA_FUNCTION_FAILED;3310	} else if (abt->nport_handle != cpu_to_le16(0)) {3311		ql_dbg(ql_dbg_mbx, vha, 0x1090,3312		    "Failed to complete IOCB -- completion status (%x).\n",3313		    le16_to_cpu(abt->nport_handle));3314		if (abt->nport_handle == cpu_to_le16(CS_IOCB_ERROR))3315			rval = QLA_FUNCTION_PARAMETER_ERROR;3316		else3317			rval = QLA_FUNCTION_FAILED;3318	} else {3319		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,3320		    "Done %s.\n", __func__);3321	}3322	if (rval == QLA_SUCCESS)3323		qla_nvme_abort_process_comp_status(abt, sp);3324 3325	qla_wait_nvme_release_cmd_kref(sp);3326 3327	dma_pool_free(ha->s_dma_pool, abt, abt_dma);3328 3329	return rval;3330}3331 3332struct tsk_mgmt_cmd {3333	union {3334		struct tsk_mgmt_entry tsk;3335		struct sts_entry_24xx sts;3336	} p;3337};3338 3339static int3340__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,3341    uint64_t l, int tag)3342{3343	int		rval, rval2;3344	struct tsk_mgmt_cmd *tsk;3345	struct sts_entry_24xx *sts;3346	dma_addr_t	tsk_dma;3347	scsi_qla_host_t *vha;3348	struct qla_hw_data *ha;3349	struct req_que *req;3350	struct qla_qpair *qpair;3351 3352	vha = fcport->vha;3353	ha = vha->hw;3354	req = vha->req;3355 3356	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,3357	    "Entered %s.\n", __func__);3358 3359	if (vha->vp_idx && vha->qpair) {3360		/* NPIV port */3361		qpair = vha->qpair;3362		req = qpair->req;3363	}3364 3365	tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);3366	if (tsk == NULL) {3367		ql_log(ql_log_warn, vha, 0x1093,3368		    "Failed to allocate task management IOCB.\n");3369		return QLA_MEMORY_ALLOC_FAILED;3370	}3371 3372	tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;3373	tsk->p.tsk.entry_count = 1;3374	tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle);3375	tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);3376	tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);3377	tsk->p.tsk.control_flags = cpu_to_le32(type);3378	tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;3379	tsk->p.tsk.port_id[1] = fcport->d_id.b.area;3380	tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;3381	tsk->p.tsk.vp_index = fcport->vha->vp_idx;3382	if (type == TCF_LUN_RESET) {3383		int_to_scsilun(l, &tsk->p.tsk.lun);3384		host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,3385		    sizeof(tsk->p.tsk.lun));3386	}3387 3388	sts = &tsk->p.sts;3389	rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);3390	if (rval != QLA_SUCCESS) {3391		ql_dbg(ql_dbg_mbx, vha, 0x1094,3392		    "Failed to issue %s reset IOCB (%x).\n", name, rval);3393	} else if (sts->entry_status != 0) {3394		ql_dbg(ql_dbg_mbx, vha, 0x1095,3395		    "Failed to complete IOCB -- error status (%x).\n",3396		    sts->entry_status);3397		rval = QLA_FUNCTION_FAILED;3398	} else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {3399		ql_dbg(ql_dbg_mbx, vha, 0x1096,3400		    "Failed to complete IOCB -- completion status (%x).\n",3401		    le16_to_cpu(sts->comp_status));3402		rval = QLA_FUNCTION_FAILED;3403	} else if (le16_to_cpu(sts->scsi_status) &3404	    SS_RESPONSE_INFO_LEN_VALID) {3405		if (le32_to_cpu(sts->rsp_data_len) < 4) {3406			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,3407			    "Ignoring inconsistent data length -- not enough "3408			    "response info (%d).\n",3409			    le32_to_cpu(sts->rsp_data_len));3410		} else if (sts->data[3]) {3411			ql_dbg(ql_dbg_mbx, vha, 0x1098,3412			    "Failed to complete IOCB -- response (%x).\n",3413			    sts->data[3]);3414			rval = QLA_FUNCTION_FAILED;3415		}3416	}3417 3418	/* Issue marker IOCB. */3419	rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l,3420	    type == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);3421	if (rval2 != QLA_SUCCESS) {3422		ql_dbg(ql_dbg_mbx, vha, 0x1099,3423		    "Failed to issue marker IOCB (%x).\n", rval2);3424	} else {3425		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,3426		    "Done %s.\n", __func__);3427	}3428 3429	dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);3430 3431	return rval;3432}3433 3434int3435qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)3436{3437	struct qla_hw_data *ha = fcport->vha->hw;3438 3439	if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))3440		return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);3441 3442	return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);3443}3444 3445int3446qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)3447{3448	struct qla_hw_data *ha = fcport->vha->hw;3449 3450	if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))3451		return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);3452 3453	return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);3454}3455 3456int3457qla2x00_system_error(scsi_qla_host_t *vha)3458{3459	int rval;3460	mbx_cmd_t mc;3461	mbx_cmd_t *mcp = &mc;3462	struct qla_hw_data *ha = vha->hw;3463 3464	if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))3465		return QLA_FUNCTION_FAILED;3466 3467	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,3468	    "Entered %s.\n", __func__);3469 3470	mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;3471	mcp->out_mb = MBX_0;3472	mcp->in_mb = MBX_0;3473	mcp->tov = 5;3474	mcp->flags = 0;3475	rval = qla2x00_mailbox_command(vha, mcp);3476 3477	if (rval != QLA_SUCCESS) {3478		ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);3479	} else {3480		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,3481		    "Done %s.\n", __func__);3482	}3483 3484	return rval;3485}3486 3487int3488qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)3489{3490	int rval;3491	mbx_cmd_t mc;3492	mbx_cmd_t *mcp = &mc;3493 3494	if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&3495	    !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))3496		return QLA_FUNCTION_FAILED;3497 3498	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,3499	    "Entered %s.\n", __func__);3500 3501	mcp->mb[0] = MBC_WRITE_SERDES;3502	mcp->mb[1] = addr;3503	if (IS_QLA2031(vha->hw))3504		mcp->mb[2] = data & 0xff;3505	else3506		mcp->mb[2] = data;3507 3508	mcp->mb[3] = 0;3509	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;3510	mcp->in_mb = MBX_0;3511	mcp->tov = MBX_TOV_SECONDS;3512	mcp->flags = 0;3513	rval = qla2x00_mailbox_command(vha, mcp);3514 3515	if (rval != QLA_SUCCESS) {3516		ql_dbg(ql_dbg_mbx, vha, 0x1183,3517		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3518	} else {3519		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,3520		    "Done %s.\n", __func__);3521	}3522 3523	return rval;3524}3525 3526int3527qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)3528{3529	int rval;3530	mbx_cmd_t mc;3531	mbx_cmd_t *mcp = &mc;3532 3533	if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&3534	    !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))3535		return QLA_FUNCTION_FAILED;3536 3537	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,3538	    "Entered %s.\n", __func__);3539 3540	mcp->mb[0] = MBC_READ_SERDES;3541	mcp->mb[1] = addr;3542	mcp->mb[3] = 0;3543	mcp->out_mb = MBX_3|MBX_1|MBX_0;3544	mcp->in_mb = MBX_1|MBX_0;3545	mcp->tov = MBX_TOV_SECONDS;3546	mcp->flags = 0;3547	rval = qla2x00_mailbox_command(vha, mcp);3548 3549	if (IS_QLA2031(vha->hw))3550		*data = mcp->mb[1] & 0xff;3551	else3552		*data = mcp->mb[1];3553 3554	if (rval != QLA_SUCCESS) {3555		ql_dbg(ql_dbg_mbx, vha, 0x1186,3556		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3557	} else {3558		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,3559		    "Done %s.\n", __func__);3560	}3561 3562	return rval;3563}3564 3565int3566qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)3567{3568	int rval;3569	mbx_cmd_t mc;3570	mbx_cmd_t *mcp = &mc;3571 3572	if (!IS_QLA8044(vha->hw))3573		return QLA_FUNCTION_FAILED;3574 3575	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0,3576	    "Entered %s.\n", __func__);3577 3578	mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;3579	mcp->mb[1] = HCS_WRITE_SERDES;3580	mcp->mb[3] = LSW(addr);3581	mcp->mb[4] = MSW(addr);3582	mcp->mb[5] = LSW(data);3583	mcp->mb[6] = MSW(data);3584	mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;3585	mcp->in_mb = MBX_0;3586	mcp->tov = MBX_TOV_SECONDS;3587	mcp->flags = 0;3588	rval = qla2x00_mailbox_command(vha, mcp);3589 3590	if (rval != QLA_SUCCESS) {3591		ql_dbg(ql_dbg_mbx, vha, 0x11a1,3592		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3593	} else {3594		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,3595		    "Done %s.\n", __func__);3596	}3597 3598	return rval;3599}3600 3601int3602qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)3603{3604	int rval;3605	mbx_cmd_t mc;3606	mbx_cmd_t *mcp = &mc;3607 3608	if (!IS_QLA8044(vha->hw))3609		return QLA_FUNCTION_FAILED;3610 3611	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,3612	    "Entered %s.\n", __func__);3613 3614	mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;3615	mcp->mb[1] = HCS_READ_SERDES;3616	mcp->mb[3] = LSW(addr);3617	mcp->mb[4] = MSW(addr);3618	mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;3619	mcp->in_mb = MBX_2|MBX_1|MBX_0;3620	mcp->tov = MBX_TOV_SECONDS;3621	mcp->flags = 0;3622	rval = qla2x00_mailbox_command(vha, mcp);3623 3624	*data = mcp->mb[2] << 16 | mcp->mb[1];3625 3626	if (rval != QLA_SUCCESS) {3627		ql_dbg(ql_dbg_mbx, vha, 0x118a,3628		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3629	} else {3630		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,3631		    "Done %s.\n", __func__);3632	}3633 3634	return rval;3635}3636 3637/**3638 * qla2x00_set_serdes_params() -3639 * @vha: HA context3640 * @sw_em_1g: serial link options3641 * @sw_em_2g: serial link options3642 * @sw_em_4g: serial link options3643 *3644 * Returns3645 */3646int3647qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,3648    uint16_t sw_em_2g, uint16_t sw_em_4g)3649{3650	int rval;3651	mbx_cmd_t mc;3652	mbx_cmd_t *mcp = &mc;3653 3654	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,3655	    "Entered %s.\n", __func__);3656 3657	mcp->mb[0] = MBC_SERDES_PARAMS;3658	mcp->mb[1] = BIT_0;3659	mcp->mb[2] = sw_em_1g | BIT_15;3660	mcp->mb[3] = sw_em_2g | BIT_15;3661	mcp->mb[4] = sw_em_4g | BIT_15;3662	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;3663	mcp->in_mb = MBX_0;3664	mcp->tov = MBX_TOV_SECONDS;3665	mcp->flags = 0;3666	rval = qla2x00_mailbox_command(vha, mcp);3667 3668	if (rval != QLA_SUCCESS) {3669		/*EMPTY*/3670		ql_dbg(ql_dbg_mbx, vha, 0x109f,3671		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);3672	} else {3673		/*EMPTY*/3674		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,3675		    "Done %s.\n", __func__);3676	}3677 3678	return rval;3679}3680 3681int3682qla2x00_stop_firmware(scsi_qla_host_t *vha)3683{3684	int rval;3685	mbx_cmd_t mc;3686	mbx_cmd_t *mcp = &mc;3687 3688	if (!IS_FWI2_CAPABLE(vha->hw))3689		return QLA_FUNCTION_FAILED;3690 3691	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,3692	    "Entered %s.\n", __func__);3693 3694	mcp->mb[0] = MBC_STOP_FIRMWARE;3695	mcp->mb[1] = 0;3696	mcp->out_mb = MBX_1|MBX_0;3697	mcp->in_mb = MBX_0;3698	mcp->tov = 5;3699	mcp->flags = 0;3700	rval = qla2x00_mailbox_command(vha, mcp);3701 3702	if (rval != QLA_SUCCESS) {3703		ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);3704		if (mcp->mb[0] == MBS_INVALID_COMMAND)3705			rval = QLA_INVALID_COMMAND;3706	} else {3707		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,3708		    "Done %s.\n", __func__);3709	}3710 3711	return rval;3712}3713 3714int3715qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,3716    uint16_t buffers)3717{3718	int rval;3719	mbx_cmd_t mc;3720	mbx_cmd_t *mcp = &mc;3721 3722	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,3723	    "Entered %s.\n", __func__);3724 3725	if (!IS_FWI2_CAPABLE(vha->hw))3726		return QLA_FUNCTION_FAILED;3727 3728	if (unlikely(pci_channel_offline(vha->hw->pdev)))3729		return QLA_FUNCTION_FAILED;3730 3731	mcp->mb[0] = MBC_TRACE_CONTROL;3732	mcp->mb[1] = TC_EFT_ENABLE;3733	mcp->mb[2] = LSW(eft_dma);3734	mcp->mb[3] = MSW(eft_dma);3735	mcp->mb[4] = LSW(MSD(eft_dma));3736	mcp->mb[5] = MSW(MSD(eft_dma));3737	mcp->mb[6] = buffers;3738	mcp->mb[7] = TC_AEN_DISABLE;3739	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;3740	mcp->in_mb = MBX_1|MBX_0;3741	mcp->tov = MBX_TOV_SECONDS;3742	mcp->flags = 0;3743	rval = qla2x00_mailbox_command(vha, mcp);3744	if (rval != QLA_SUCCESS) {3745		ql_dbg(ql_dbg_mbx, vha, 0x10a5,3746		    "Failed=%x mb[0]=%x mb[1]=%x.\n",3747		    rval, mcp->mb[0], mcp->mb[1]);3748	} else {3749		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,3750		    "Done %s.\n", __func__);3751	}3752 3753	return rval;3754}3755 3756int3757qla2x00_disable_eft_trace(scsi_qla_host_t *vha)3758{3759	int rval;3760	mbx_cmd_t mc;3761	mbx_cmd_t *mcp = &mc;3762 3763	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,3764	    "Entered %s.\n", __func__);3765 3766	if (!IS_FWI2_CAPABLE(vha->hw))3767		return QLA_FUNCTION_FAILED;3768 3769	if (unlikely(pci_channel_offline(vha->hw->pdev)))3770		return QLA_FUNCTION_FAILED;3771 3772	mcp->mb[0] = MBC_TRACE_CONTROL;3773	mcp->mb[1] = TC_EFT_DISABLE;3774	mcp->out_mb = MBX_1|MBX_0;3775	mcp->in_mb = MBX_1|MBX_0;3776	mcp->tov = MBX_TOV_SECONDS;3777	mcp->flags = 0;3778	rval = qla2x00_mailbox_command(vha, mcp);3779	if (rval != QLA_SUCCESS) {3780		ql_dbg(ql_dbg_mbx, vha, 0x10a8,3781		    "Failed=%x mb[0]=%x mb[1]=%x.\n",3782		    rval, mcp->mb[0], mcp->mb[1]);3783	} else {3784		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,3785		    "Done %s.\n", __func__);3786	}3787 3788	return rval;3789}3790 3791int3792qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,3793    uint16_t buffers, uint16_t *mb, uint32_t *dwords)3794{3795	int rval;3796	mbx_cmd_t mc;3797	mbx_cmd_t *mcp = &mc;3798 3799	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,3800	    "Entered %s.\n", __func__);3801 3802	if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&3803	    !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&3804	    !IS_QLA28XX(vha->hw))3805		return QLA_FUNCTION_FAILED;3806 3807	if (unlikely(pci_channel_offline(vha->hw->pdev)))3808		return QLA_FUNCTION_FAILED;3809 3810	mcp->mb[0] = MBC_TRACE_CONTROL;3811	mcp->mb[1] = TC_FCE_ENABLE;3812	mcp->mb[2] = LSW(fce_dma);3813	mcp->mb[3] = MSW(fce_dma);3814	mcp->mb[4] = LSW(MSD(fce_dma));3815	mcp->mb[5] = MSW(MSD(fce_dma));3816	mcp->mb[6] = buffers;3817	mcp->mb[7] = TC_AEN_DISABLE;3818	mcp->mb[8] = 0;3819	mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;3820	mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;3821	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|3822	    MBX_1|MBX_0;3823	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;3824	mcp->tov = MBX_TOV_SECONDS;3825	mcp->flags = 0;3826	rval = qla2x00_mailbox_command(vha, mcp);3827	if (rval != QLA_SUCCESS) {3828		ql_dbg(ql_dbg_mbx, vha, 0x10ab,3829		    "Failed=%x mb[0]=%x mb[1]=%x.\n",3830		    rval, mcp->mb[0], mcp->mb[1]);3831	} else {3832		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,3833		    "Done %s.\n", __func__);3834 3835		if (mb)3836			memcpy(mb, mcp->mb, 8 * sizeof(*mb));3837		if (dwords)3838			*dwords = buffers;3839	}3840 3841	return rval;3842}3843 3844int3845qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)3846{3847	int rval;3848	mbx_cmd_t mc;3849	mbx_cmd_t *mcp = &mc;3850 3851	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,3852	    "Entered %s.\n", __func__);3853 3854	if (!IS_FWI2_CAPABLE(vha->hw))3855		return QLA_FUNCTION_FAILED;3856 3857	if (unlikely(pci_channel_offline(vha->hw->pdev)))3858		return QLA_FUNCTION_FAILED;3859 3860	mcp->mb[0] = MBC_TRACE_CONTROL;3861	mcp->mb[1] = TC_FCE_DISABLE;3862	mcp->mb[2] = TC_FCE_DISABLE_TRACE;3863	mcp->out_mb = MBX_2|MBX_1|MBX_0;3864	mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|3865	    MBX_1|MBX_0;3866	mcp->tov = MBX_TOV_SECONDS;3867	mcp->flags = 0;3868	rval = qla2x00_mailbox_command(vha, mcp);3869	if (rval != QLA_SUCCESS) {3870		ql_dbg(ql_dbg_mbx, vha, 0x10ae,3871		    "Failed=%x mb[0]=%x mb[1]=%x.\n",3872		    rval, mcp->mb[0], mcp->mb[1]);3873	} else {3874		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,3875		    "Done %s.\n", __func__);3876 3877		if (wr)3878			*wr = (uint64_t) mcp->mb[5] << 48 |3879			    (uint64_t) mcp->mb[4] << 32 |3880			    (uint64_t) mcp->mb[3] << 16 |3881			    (uint64_t) mcp->mb[2];3882		if (rd)3883			*rd = (uint64_t) mcp->mb[9] << 48 |3884			    (uint64_t) mcp->mb[8] << 32 |3885			    (uint64_t) mcp->mb[7] << 16 |3886			    (uint64_t) mcp->mb[6];3887	}3888 3889	return rval;3890}3891 3892int3893qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,3894	uint16_t *port_speed, uint16_t *mb)3895{3896	int rval;3897	mbx_cmd_t mc;3898	mbx_cmd_t *mcp = &mc;3899 3900	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,3901	    "Entered %s.\n", __func__);3902 3903	if (!IS_IIDMA_CAPABLE(vha->hw))3904		return QLA_FUNCTION_FAILED;3905 3906	mcp->mb[0] = MBC_PORT_PARAMS;3907	mcp->mb[1] = loop_id;3908	mcp->mb[2] = mcp->mb[3] = 0;3909	mcp->mb[9] = vha->vp_idx;3910	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;3911	mcp->in_mb = MBX_3|MBX_1|MBX_0;3912	mcp->tov = MBX_TOV_SECONDS;3913	mcp->flags = 0;3914	rval = qla2x00_mailbox_command(vha, mcp);3915 3916	/* Return mailbox statuses. */3917	if (mb) {3918		mb[0] = mcp->mb[0];3919		mb[1] = mcp->mb[1];3920		mb[3] = mcp->mb[3];3921	}3922 3923	if (rval != QLA_SUCCESS) {3924		ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);3925	} else {3926		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,3927		    "Done %s.\n", __func__);3928		if (port_speed)3929			*port_speed = mcp->mb[3];3930	}3931 3932	return rval;3933}3934 3935int3936qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,3937    uint16_t port_speed, uint16_t *mb)3938{3939	int rval;3940	mbx_cmd_t mc;3941	mbx_cmd_t *mcp = &mc;3942 3943	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,3944	    "Entered %s.\n", __func__);3945 3946	if (!IS_IIDMA_CAPABLE(vha->hw))3947		return QLA_FUNCTION_FAILED;3948 3949	mcp->mb[0] = MBC_PORT_PARAMS;3950	mcp->mb[1] = loop_id;3951	mcp->mb[2] = BIT_0;3952	mcp->mb[3] = port_speed & 0x3F;3953	mcp->mb[9] = vha->vp_idx;3954	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;3955	mcp->in_mb = MBX_3|MBX_1|MBX_0;3956	mcp->tov = MBX_TOV_SECONDS;3957	mcp->flags = 0;3958	rval = qla2x00_mailbox_command(vha, mcp);3959 3960	/* Return mailbox statuses. */3961	if (mb) {3962		mb[0] = mcp->mb[0];3963		mb[1] = mcp->mb[1];3964		mb[3] = mcp->mb[3];3965	}3966 3967	if (rval != QLA_SUCCESS) {3968		ql_dbg(ql_dbg_mbx, vha, 0x10b4,3969		    "Failed=%x.\n", rval);3970	} else {3971		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,3972		    "Done %s.\n", __func__);3973	}3974 3975	return rval;3976}3977 3978void3979qla24xx_report_id_acquisition(scsi_qla_host_t *vha,3980	struct vp_rpt_id_entry_24xx *rptid_entry)3981{3982	struct qla_hw_data *ha = vha->hw;3983	scsi_qla_host_t *vp = NULL;3984	unsigned long   flags;3985	int found;3986	port_id_t id;3987	struct fc_port *fcport;3988 3989	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,3990	    "Entered %s.\n", __func__);3991 3992	if (rptid_entry->entry_status != 0)3993		return;3994 3995	id.b.domain = rptid_entry->port_id[2];3996	id.b.area   = rptid_entry->port_id[1];3997	id.b.al_pa  = rptid_entry->port_id[0];3998	id.b.rsvd_1 = 0;3999	ha->flags.n2n_ae = 0;4000 4001	if (rptid_entry->format == 0) {4002		/* loop */4003		ql_dbg(ql_dbg_async, vha, 0x10b7,4004		    "Format 0 : Number of VPs setup %d, number of "4005		    "VPs acquired %d.\n", rptid_entry->vp_setup,4006		    rptid_entry->vp_acquired);4007		ql_dbg(ql_dbg_async, vha, 0x10b8,4008		    "Primary port id %02x%02x%02x.\n",4009		    rptid_entry->port_id[2], rptid_entry->port_id[1],4010		    rptid_entry->port_id[0]);4011		ha->current_topology = ISP_CFG_NL;4012		qla_update_host_map(vha, id);4013 4014	} else if (rptid_entry->format == 1) {4015		/* fabric */4016		ql_dbg(ql_dbg_async, vha, 0x10b9,4017		    "Format 1: VP[%d] enabled - status %d - with "4018		    "port id %02x%02x%02x.\n", rptid_entry->vp_idx,4019			rptid_entry->vp_status,4020		    rptid_entry->port_id[2], rptid_entry->port_id[1],4021		    rptid_entry->port_id[0]);4022		ql_dbg(ql_dbg_async, vha, 0x5075,4023		   "Format 1: Remote WWPN %8phC.\n",4024		   rptid_entry->u.f1.port_name);4025 4026		ql_dbg(ql_dbg_async, vha, 0x5075,4027		   "Format 1: WWPN %8phC.\n",4028		   vha->port_name);4029 4030		switch (rptid_entry->u.f1.flags & TOPO_MASK) {4031		case TOPO_N2N:4032			ha->current_topology = ISP_CFG_N;4033			spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);4034			list_for_each_entry(fcport, &vha->vp_fcports, list) {4035				fcport->scan_state = QLA_FCPORT_SCAN;4036				fcport->n2n_flag = 0;4037			}4038			id.b24 = 0;4039			if (wwn_to_u64(vha->port_name) >4040			    wwn_to_u64(rptid_entry->u.f1.port_name)) {4041				vha->d_id.b24 = 0;4042				vha->d_id.b.al_pa = 1;4043				ha->flags.n2n_bigger = 1;4044 4045				id.b.al_pa = 2;4046				ql_dbg(ql_dbg_async, vha, 0x5075,4047				    "Format 1: assign local id %x remote id %x\n",4048				    vha->d_id.b24, id.b24);4049			} else {4050				ql_dbg(ql_dbg_async, vha, 0x5075,4051				    "Format 1: Remote login - Waiting for WWPN %8phC.\n",4052				    rptid_entry->u.f1.port_name);4053				ha->flags.n2n_bigger = 0;4054			}4055 4056			fcport = qla2x00_find_fcport_by_wwpn(vha,4057			    rptid_entry->u.f1.port_name, 1);4058			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);4059 4060 4061			if (fcport) {4062				fcport->plogi_nack_done_deadline = jiffies + HZ;4063				fcport->dm_login_expire = jiffies +4064					QLA_N2N_WAIT_TIME * HZ;4065				fcport->scan_state = QLA_FCPORT_FOUND;4066				fcport->n2n_flag = 1;4067				fcport->keep_nport_handle = 1;4068				fcport->login_retry = vha->hw->login_retry_count;4069				fcport->fc4_type = FS_FC4TYPE_FCP;4070				if (vha->flags.nvme_enabled)4071					fcport->fc4_type |= FS_FC4TYPE_NVME;4072 4073				if (wwn_to_u64(vha->port_name) >4074				    wwn_to_u64(fcport->port_name)) {4075					fcport->d_id = id;4076				}4077 4078				switch (fcport->disc_state) {4079				case DSC_DELETED:4080					set_bit(RELOGIN_NEEDED,4081					    &vha->dpc_flags);4082					break;4083				case DSC_DELETE_PEND:4084					break;4085				default:4086					qlt_schedule_sess_for_deletion(fcport);4087					break;4088				}4089			} else {4090				qla24xx_post_newsess_work(vha, &id,4091				    rptid_entry->u.f1.port_name,4092				    rptid_entry->u.f1.node_name,4093				    NULL,4094				    FS_FCP_IS_N2N);4095			}4096 4097			/* if our portname is higher then initiate N2N login */4098 4099			set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);4100			return;4101		case TOPO_FL:4102			ha->current_topology = ISP_CFG_FL;4103			break;4104		case TOPO_F:4105			ha->current_topology = ISP_CFG_F;4106			break;4107		default:4108			break;4109		}4110 4111		ha->flags.gpsc_supported = 1;4112		ha->current_topology = ISP_CFG_F;4113		/* buffer to buffer credit flag */4114		vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;4115 4116		if (rptid_entry->vp_idx == 0) {4117			if (rptid_entry->vp_status == VP_STAT_COMPL) {4118				/* FA-WWN is only for physical port */4119				if (qla_ini_mode_enabled(vha) &&4120				    ha->flags.fawwpn_enabled &&4121				    (rptid_entry->u.f1.flags &4122				     BIT_6)) {4123					memcpy(vha->port_name,4124					    rptid_entry->u.f1.port_name,4125					    WWN_SIZE);4126				}4127 4128				qla_update_host_map(vha, id);4129			}4130 4131			set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);4132			set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);4133		} else {4134			if (rptid_entry->vp_status != VP_STAT_COMPL &&4135				rptid_entry->vp_status != VP_STAT_ID_CHG) {4136				ql_dbg(ql_dbg_mbx, vha, 0x10ba,4137				    "Could not acquire ID for VP[%d].\n",4138				    rptid_entry->vp_idx);4139				return;4140			}4141 4142			found = 0;4143			spin_lock_irqsave(&ha->vport_slock, flags);4144			list_for_each_entry(vp, &ha->vp_list, list) {4145				if (rptid_entry->vp_idx == vp->vp_idx) {4146					found = 1;4147					break;4148				}4149			}4150			spin_unlock_irqrestore(&ha->vport_slock, flags);4151 4152			if (!found)4153				return;4154 4155			qla_update_host_map(vp, id);4156 4157			/*4158			 * Cannot configure here as we are still sitting on the4159			 * response queue. Handle it in dpc context.4160			 */4161			set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);4162			set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);4163			set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);4164		}4165		set_bit(VP_DPC_NEEDED, &vha->dpc_flags);4166		qla2xxx_wake_dpc(vha);4167	} else if (rptid_entry->format == 2) {4168		ql_dbg(ql_dbg_async, vha, 0x505f,4169		    "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",4170		    rptid_entry->port_id[2], rptid_entry->port_id[1],4171		    rptid_entry->port_id[0]);4172 4173		ql_dbg(ql_dbg_async, vha, 0x5075,4174		    "N2N: Remote WWPN %8phC.\n",4175		    rptid_entry->u.f2.port_name);4176 4177		/* N2N.  direct connect */4178		ha->current_topology = ISP_CFG_N;4179		ha->flags.rida_fmt2 = 1;4180		vha->d_id.b.domain = rptid_entry->port_id[2];4181		vha->d_id.b.area = rptid_entry->port_id[1];4182		vha->d_id.b.al_pa = rptid_entry->port_id[0];4183 4184		ha->flags.n2n_ae = 1;4185		spin_lock_irqsave(&ha->vport_slock, flags);4186		qla_update_vp_map(vha, SET_AL_PA);4187		spin_unlock_irqrestore(&ha->vport_slock, flags);4188 4189		list_for_each_entry(fcport, &vha->vp_fcports, list) {4190			fcport->scan_state = QLA_FCPORT_SCAN;4191			fcport->n2n_flag = 0;4192		}4193 4194		fcport = qla2x00_find_fcport_by_wwpn(vha,4195		    rptid_entry->u.f2.port_name, 1);4196 4197		if (fcport) {4198			fcport->login_retry = vha->hw->login_retry_count;4199			fcport->plogi_nack_done_deadline = jiffies + HZ;4200			fcport->scan_state = QLA_FCPORT_FOUND;4201			fcport->keep_nport_handle = 1;4202			fcport->n2n_flag = 1;4203			fcport->d_id.b.domain =4204				rptid_entry->u.f2.remote_nport_id[2];4205			fcport->d_id.b.area =4206				rptid_entry->u.f2.remote_nport_id[1];4207			fcport->d_id.b.al_pa =4208				rptid_entry->u.f2.remote_nport_id[0];4209 4210			/*4211			 * For the case where remote port sending PRLO, FW4212			 * sends up RIDA Format 2 as an indication of session4213			 * loss. In other word, FW state change from PRLI4214			 * complete back to PLOGI complete. Delete the4215			 * session and let relogin drive the reconnect.4216			 */4217			if (atomic_read(&fcport->state) == FCS_ONLINE)4218				qlt_schedule_sess_for_deletion(fcport);4219		}4220	}4221}4222 4223/*4224 * qla24xx_modify_vp_config4225 *	Change VP configuration for vha4226 *4227 * Input:4228 *	vha = adapter block pointer.4229 *4230 * Returns:4231 *	qla2xxx local function return status code.4232 *4233 * Context:4234 *	Kernel context.4235 */4236int4237qla24xx_modify_vp_config(scsi_qla_host_t *vha)4238{4239	int		rval;4240	struct vp_config_entry_24xx *vpmod;4241	dma_addr_t	vpmod_dma;4242	struct qla_hw_data *ha = vha->hw;4243	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);4244 4245	/* This can be called by the parent */4246 4247	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,4248	    "Entered %s.\n", __func__);4249 4250	vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);4251	if (!vpmod) {4252		ql_log(ql_log_warn, vha, 0x10bc,4253		    "Failed to allocate modify VP IOCB.\n");4254		return QLA_MEMORY_ALLOC_FAILED;4255	}4256 4257	vpmod->entry_type = VP_CONFIG_IOCB_TYPE;4258	vpmod->entry_count = 1;4259	vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;4260	vpmod->vp_count = 1;4261	vpmod->vp_index1 = vha->vp_idx;4262	vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;4263 4264	qlt_modify_vp_config(vha, vpmod);4265 4266	memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);4267	memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);4268	vpmod->entry_count = 1;4269 4270	rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);4271	if (rval != QLA_SUCCESS) {4272		ql_dbg(ql_dbg_mbx, vha, 0x10bd,4273		    "Failed to issue VP config IOCB (%x).\n", rval);4274	} else if (vpmod->comp_status != 0) {4275		ql_dbg(ql_dbg_mbx, vha, 0x10be,4276		    "Failed to complete IOCB -- error status (%x).\n",4277		    vpmod->comp_status);4278		rval = QLA_FUNCTION_FAILED;4279	} else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {4280		ql_dbg(ql_dbg_mbx, vha, 0x10bf,4281		    "Failed to complete IOCB -- completion status (%x).\n",4282		    le16_to_cpu(vpmod->comp_status));4283		rval = QLA_FUNCTION_FAILED;4284	} else {4285		/* EMPTY */4286		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,4287		    "Done %s.\n", __func__);4288		fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);4289	}4290	dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);4291 4292	return rval;4293}4294 4295/*4296 * qla2x00_send_change_request4297 *	Receive or disable RSCN request from fabric controller4298 *4299 * Input:4300 *	ha = adapter block pointer4301 *	format = registration format:4302 *		0 - Reserved4303 *		1 - Fabric detected registration4304 *		2 - N_port detected registration4305 *		3 - Full registration4306 *		FF - clear registration4307 *	vp_idx = Virtual port index4308 *4309 * Returns:4310 *	qla2x00 local function return status code.4311 *4312 * Context:4313 *	Kernel Context4314 */4315 4316int4317qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,4318			    uint16_t vp_idx)4319{4320	int rval;4321	mbx_cmd_t mc;4322	mbx_cmd_t *mcp = &mc;4323 4324	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,4325	    "Entered %s.\n", __func__);4326 4327	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;4328	mcp->mb[1] = format;4329	mcp->mb[9] = vp_idx;4330	mcp->out_mb = MBX_9|MBX_1|MBX_0;4331	mcp->in_mb = MBX_0|MBX_1;4332	mcp->tov = MBX_TOV_SECONDS;4333	mcp->flags = 0;4334	rval = qla2x00_mailbox_command(vha, mcp);4335 4336	if (rval == QLA_SUCCESS) {4337		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {4338			rval = BIT_1;4339		}4340	} else4341		rval = BIT_1;4342 4343	return rval;4344}4345 4346int4347qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,4348    uint32_t size)4349{4350	int rval;4351	mbx_cmd_t mc;4352	mbx_cmd_t *mcp = &mc;4353 4354	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,4355	    "Entered %s.\n", __func__);4356 4357	if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {4358		mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;4359		mcp->mb[8] = MSW(addr);4360		mcp->mb[10] = 0;4361		mcp->out_mb = MBX_10|MBX_8|MBX_0;4362	} else {4363		mcp->mb[0] = MBC_DUMP_RISC_RAM;4364		mcp->out_mb = MBX_0;4365	}4366	mcp->mb[1] = LSW(addr);4367	mcp->mb[2] = MSW(req_dma);4368	mcp->mb[3] = LSW(req_dma);4369	mcp->mb[6] = MSW(MSD(req_dma));4370	mcp->mb[7] = LSW(MSD(req_dma));4371	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;4372	if (IS_FWI2_CAPABLE(vha->hw)) {4373		mcp->mb[4] = MSW(size);4374		mcp->mb[5] = LSW(size);4375		mcp->out_mb |= MBX_5|MBX_4;4376	} else {4377		mcp->mb[4] = LSW(size);4378		mcp->out_mb |= MBX_4;4379	}4380 4381	mcp->in_mb = MBX_0;4382	mcp->tov = MBX_TOV_SECONDS;4383	mcp->flags = 0;4384	rval = qla2x00_mailbox_command(vha, mcp);4385 4386	if (rval != QLA_SUCCESS) {4387		ql_dbg(ql_dbg_mbx, vha, 0x1008,4388		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);4389	} else {4390		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,4391		    "Done %s.\n", __func__);4392	}4393 4394	return rval;4395}4396/* 84XX Support **************************************************************/4397 4398struct cs84xx_mgmt_cmd {4399	union {4400		struct verify_chip_entry_84xx req;4401		struct verify_chip_rsp_84xx rsp;4402	} p;4403};4404 4405int4406qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)4407{4408	int rval, retry;4409	struct cs84xx_mgmt_cmd *mn;4410	dma_addr_t mn_dma;4411	uint16_t options;4412	unsigned long flags;4413	struct qla_hw_data *ha = vha->hw;4414 4415	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,4416	    "Entered %s.\n", __func__);4417 4418	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);4419	if (mn == NULL) {4420		return QLA_MEMORY_ALLOC_FAILED;4421	}4422 4423	/* Force Update? */4424	options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;4425	/* Diagnostic firmware? */4426	/* options |= MENLO_DIAG_FW; */4427	/* We update the firmware with only one data sequence. */4428	options |= VCO_END_OF_DATA;4429 4430	do {4431		retry = 0;4432		memset(mn, 0, sizeof(*mn));4433		mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;4434		mn->p.req.entry_count = 1;4435		mn->p.req.options = cpu_to_le16(options);4436 4437		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,4438		    "Dump of Verify Request.\n");4439		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,4440		    mn, sizeof(*mn));4441 4442		rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);4443		if (rval != QLA_SUCCESS) {4444			ql_dbg(ql_dbg_mbx, vha, 0x10cb,4445			    "Failed to issue verify IOCB (%x).\n", rval);4446			goto verify_done;4447		}4448 4449		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,4450		    "Dump of Verify Response.\n");4451		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,4452		    mn, sizeof(*mn));4453 4454		status[0] = le16_to_cpu(mn->p.rsp.comp_status);4455		status[1] = status[0] == CS_VCS_CHIP_FAILURE ?4456		    le16_to_cpu(mn->p.rsp.failure_code) : 0;4457		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,4458		    "cs=%x fc=%x.\n", status[0], status[1]);4459 4460		if (status[0] != CS_COMPLETE) {4461			rval = QLA_FUNCTION_FAILED;4462			if (!(options & VCO_DONT_UPDATE_FW)) {4463				ql_dbg(ql_dbg_mbx, vha, 0x10cf,4464				    "Firmware update failed. Retrying "4465				    "without update firmware.\n");4466				options |= VCO_DONT_UPDATE_FW;4467				options &= ~VCO_FORCE_UPDATE;4468				retry = 1;4469			}4470		} else {4471			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,4472			    "Firmware updated to %x.\n",4473			    le32_to_cpu(mn->p.rsp.fw_ver));4474 4475			/* NOTE: we only update OP firmware. */4476			spin_lock_irqsave(&ha->cs84xx->access_lock, flags);4477			ha->cs84xx->op_fw_version =4478			    le32_to_cpu(mn->p.rsp.fw_ver);4479			spin_unlock_irqrestore(&ha->cs84xx->access_lock,4480			    flags);4481		}4482	} while (retry);4483 4484verify_done:4485	dma_pool_free(ha->s_dma_pool, mn, mn_dma);4486 4487	if (rval != QLA_SUCCESS) {4488		ql_dbg(ql_dbg_mbx, vha, 0x10d1,4489		    "Failed=%x.\n", rval);4490	} else {4491		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,4492		    "Done %s.\n", __func__);4493	}4494 4495	return rval;4496}4497 4498int4499qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)4500{4501	int rval;4502	unsigned long flags;4503	mbx_cmd_t mc;4504	mbx_cmd_t *mcp = &mc;4505	struct qla_hw_data *ha = vha->hw;4506 4507	if (!ha->flags.fw_started)4508		return QLA_SUCCESS;4509 4510	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,4511	    "Entered %s.\n", __func__);4512 4513	if (IS_SHADOW_REG_CAPABLE(ha))4514		req->options |= BIT_13;4515 4516	mcp->mb[0] = MBC_INITIALIZE_MULTIQ;4517	mcp->mb[1] = req->options;4518	mcp->mb[2] = MSW(LSD(req->dma));4519	mcp->mb[3] = LSW(LSD(req->dma));4520	mcp->mb[6] = MSW(MSD(req->dma));4521	mcp->mb[7] = LSW(MSD(req->dma));4522	mcp->mb[5] = req->length;4523	if (req->rsp)4524		mcp->mb[10] = req->rsp->id;4525	mcp->mb[12] = req->qos;4526	mcp->mb[11] = req->vp_idx;4527	mcp->mb[13] = req->rid;4528	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))4529		mcp->mb[15] = 0;4530 4531	mcp->mb[4] = req->id;4532	/* que in ptr index */4533	mcp->mb[8] = 0;4534	/* que out ptr index */4535	mcp->mb[9] = *req->out_ptr = 0;4536	mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|4537			MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;4538	mcp->in_mb = MBX_0;4539	mcp->flags = MBX_DMA_OUT;4540	mcp->tov = MBX_TOV_SECONDS * 2;4541 4542	if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||4543	    IS_QLA28XX(ha))4544		mcp->in_mb |= MBX_1;4545	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {4546		mcp->out_mb |= MBX_15;4547		/* debug q create issue in SR-IOV */4548		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;4549	}4550 4551	spin_lock_irqsave(&ha->hardware_lock, flags);4552	if (!(req->options & BIT_0)) {4553		wrt_reg_dword(req->req_q_in, 0);4554		if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))4555			wrt_reg_dword(req->req_q_out, 0);4556	}4557	spin_unlock_irqrestore(&ha->hardware_lock, flags);4558 4559	rval = qla2x00_mailbox_command(vha, mcp);4560	if (rval != QLA_SUCCESS) {4561		ql_dbg(ql_dbg_mbx, vha, 0x10d4,4562		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);4563	} else {4564		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,4565		    "Done %s.\n", __func__);4566	}4567 4568	return rval;4569}4570 4571int4572qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)4573{4574	int rval;4575	unsigned long flags;4576	mbx_cmd_t mc;4577	mbx_cmd_t *mcp = &mc;4578	struct qla_hw_data *ha = vha->hw;4579 4580	if (!ha->flags.fw_started)4581		return QLA_SUCCESS;4582 4583	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,4584	    "Entered %s.\n", __func__);4585 4586	if (IS_SHADOW_REG_CAPABLE(ha))4587		rsp->options |= BIT_13;4588 4589	mcp->mb[0] = MBC_INITIALIZE_MULTIQ;4590	mcp->mb[1] = rsp->options;4591	mcp->mb[2] = MSW(LSD(rsp->dma));4592	mcp->mb[3] = LSW(LSD(rsp->dma));4593	mcp->mb[6] = MSW(MSD(rsp->dma));4594	mcp->mb[7] = LSW(MSD(rsp->dma));4595	mcp->mb[5] = rsp->length;4596	mcp->mb[14] = rsp->msix->entry;4597	mcp->mb[13] = rsp->rid;4598	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))4599		mcp->mb[15] = 0;4600 4601	mcp->mb[4] = rsp->id;4602	/* que in ptr index */4603	mcp->mb[8] = *rsp->in_ptr = 0;4604	/* que out ptr index */4605	mcp->mb[9] = 0;4606	mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_74607			|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;4608	mcp->in_mb = MBX_0;4609	mcp->flags = MBX_DMA_OUT;4610	mcp->tov = MBX_TOV_SECONDS * 2;4611 4612	if (IS_QLA81XX(ha)) {4613		mcp->out_mb |= MBX_12|MBX_11|MBX_10;4614		mcp->in_mb |= MBX_1;4615	} else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {4616		mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;4617		mcp->in_mb |= MBX_1;4618		/* debug q create issue in SR-IOV */4619		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;4620	}4621 4622	spin_lock_irqsave(&ha->hardware_lock, flags);4623	if (!(rsp->options & BIT_0)) {4624		wrt_reg_dword(rsp->rsp_q_out, 0);4625		if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))4626			wrt_reg_dword(rsp->rsp_q_in, 0);4627	}4628 4629	spin_unlock_irqrestore(&ha->hardware_lock, flags);4630 4631	rval = qla2x00_mailbox_command(vha, mcp);4632	if (rval != QLA_SUCCESS) {4633		ql_dbg(ql_dbg_mbx, vha, 0x10d7,4634		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);4635	} else {4636		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,4637		    "Done %s.\n", __func__);4638	}4639 4640	return rval;4641}4642 4643int4644qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)4645{4646	int rval;4647	mbx_cmd_t mc;4648	mbx_cmd_t *mcp = &mc;4649 4650	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,4651	    "Entered %s.\n", __func__);4652 4653	mcp->mb[0] = MBC_IDC_ACK;4654	memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));4655	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;4656	mcp->in_mb = MBX_0;4657	mcp->tov = MBX_TOV_SECONDS;4658	mcp->flags = 0;4659	rval = qla2x00_mailbox_command(vha, mcp);4660 4661	if (rval != QLA_SUCCESS) {4662		ql_dbg(ql_dbg_mbx, vha, 0x10da,4663		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);4664	} else {4665		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,4666		    "Done %s.\n", __func__);4667	}4668 4669	return rval;4670}4671 4672int4673qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)4674{4675	int rval;4676	mbx_cmd_t mc;4677	mbx_cmd_t *mcp = &mc;4678 4679	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,4680	    "Entered %s.\n", __func__);4681 4682	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&4683	    !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))4684		return QLA_FUNCTION_FAILED;4685 4686	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;4687	mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;4688	mcp->out_mb = MBX_1|MBX_0;4689	mcp->in_mb = MBX_1|MBX_0;4690	mcp->tov = MBX_TOV_SECONDS;4691	mcp->flags = 0;4692	rval = qla2x00_mailbox_command(vha, mcp);4693 4694	if (rval != QLA_SUCCESS) {4695		ql_dbg(ql_dbg_mbx, vha, 0x10dd,4696		    "Failed=%x mb[0]=%x mb[1]=%x.\n",4697		    rval, mcp->mb[0], mcp->mb[1]);4698	} else {4699		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,4700		    "Done %s.\n", __func__);4701		*sector_size = mcp->mb[1];4702	}4703 4704	return rval;4705}4706 4707int4708qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)4709{4710	int rval;4711	mbx_cmd_t mc;4712	mbx_cmd_t *mcp = &mc;4713 4714	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&4715	    !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))4716		return QLA_FUNCTION_FAILED;4717 4718	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,4719	    "Entered %s.\n", __func__);4720 4721	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;4722	mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :4723	    FAC_OPT_CMD_WRITE_PROTECT;4724	mcp->out_mb = MBX_1|MBX_0;4725	mcp->in_mb = MBX_1|MBX_0;4726	mcp->tov = MBX_TOV_SECONDS;4727	mcp->flags = 0;4728	rval = qla2x00_mailbox_command(vha, mcp);4729 4730	if (rval != QLA_SUCCESS) {4731		ql_dbg(ql_dbg_mbx, vha, 0x10e0,4732		    "Failed=%x mb[0]=%x mb[1]=%x.\n",4733		    rval, mcp->mb[0], mcp->mb[1]);4734	} else {4735		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,4736		    "Done %s.\n", __func__);4737	}4738 4739	return rval;4740}4741 4742int4743qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)4744{4745	int rval;4746	mbx_cmd_t mc;4747	mbx_cmd_t *mcp = &mc;4748 4749	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&4750	    !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw))4751		return QLA_FUNCTION_FAILED;4752 4753	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,4754	    "Entered %s.\n", __func__);4755 4756	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;4757	mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;4758	mcp->mb[2] = LSW(start);4759	mcp->mb[3] = MSW(start);4760	mcp->mb[4] = LSW(finish);4761	mcp->mb[5] = MSW(finish);4762	mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;4763	mcp->in_mb = MBX_2|MBX_1|MBX_0;4764	mcp->tov = MBX_TOV_SECONDS;4765	mcp->flags = 0;4766	rval = qla2x00_mailbox_command(vha, mcp);4767 4768	if (rval != QLA_SUCCESS) {4769		ql_dbg(ql_dbg_mbx, vha, 0x10e3,4770		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",4771		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);4772	} else {4773		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,4774		    "Done %s.\n", __func__);4775	}4776 4777	return rval;4778}4779 4780int4781qla81xx_fac_semaphore_access(scsi_qla_host_t *vha, int lock)4782{4783	int rval = QLA_SUCCESS;4784	mbx_cmd_t mc;4785	mbx_cmd_t *mcp = &mc;4786	struct qla_hw_data *ha = vha->hw;4787 4788	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&4789	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))4790		return rval;4791 4792	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,4793	    "Entered %s.\n", __func__);4794 4795	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;4796	mcp->mb[1] = (lock ? FAC_OPT_CMD_LOCK_SEMAPHORE :4797	    FAC_OPT_CMD_UNLOCK_SEMAPHORE);4798	mcp->out_mb = MBX_1|MBX_0;4799	mcp->in_mb = MBX_1|MBX_0;4800	mcp->tov = MBX_TOV_SECONDS;4801	mcp->flags = 0;4802	rval = qla2x00_mailbox_command(vha, mcp);4803 4804	if (rval != QLA_SUCCESS) {4805		ql_dbg(ql_dbg_mbx, vha, 0x10e3,4806		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",4807		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);4808	} else {4809		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,4810		    "Done %s.\n", __func__);4811	}4812 4813	return rval;4814}4815 4816int4817qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)4818{4819	int rval = 0;4820	mbx_cmd_t mc;4821	mbx_cmd_t *mcp = &mc;4822 4823	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,4824	    "Entered %s.\n", __func__);4825 4826	mcp->mb[0] = MBC_RESTART_MPI_FW;4827	mcp->out_mb = MBX_0;4828	mcp->in_mb = MBX_0|MBX_1;4829	mcp->tov = MBX_TOV_SECONDS;4830	mcp->flags = 0;4831	rval = qla2x00_mailbox_command(vha, mcp);4832 4833	if (rval != QLA_SUCCESS) {4834		ql_dbg(ql_dbg_mbx, vha, 0x10e6,4835		    "Failed=%x mb[0]=%x mb[1]=%x.\n",4836		    rval, mcp->mb[0], mcp->mb[1]);4837	} else {4838		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,4839		    "Done %s.\n", __func__);4840	}4841 4842	return rval;4843}4844 4845int4846qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)4847{4848	int rval;4849	mbx_cmd_t mc;4850	mbx_cmd_t *mcp = &mc;4851	int i;4852	int len;4853	__le16 *str;4854	struct qla_hw_data *ha = vha->hw;4855 4856	if (!IS_P3P_TYPE(ha))4857		return QLA_FUNCTION_FAILED;4858 4859	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,4860	    "Entered %s.\n", __func__);4861 4862	str = (__force __le16 *)version;4863	len = strlen(version);4864 4865	mcp->mb[0] = MBC_SET_RNID_PARAMS;4866	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;4867	mcp->out_mb = MBX_1|MBX_0;4868	for (i = 4; i < 16 && len; i++, str++, len -= 2) {4869		mcp->mb[i] = le16_to_cpup(str);4870		mcp->out_mb |= 1<<i;4871	}4872	for (; i < 16; i++) {4873		mcp->mb[i] = 0;4874		mcp->out_mb |= 1<<i;4875	}4876	mcp->in_mb = MBX_1|MBX_0;4877	mcp->tov = MBX_TOV_SECONDS;4878	mcp->flags = 0;4879	rval = qla2x00_mailbox_command(vha, mcp);4880 4881	if (rval != QLA_SUCCESS) {4882		ql_dbg(ql_dbg_mbx, vha, 0x117c,4883		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);4884	} else {4885		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,4886		    "Done %s.\n", __func__);4887	}4888 4889	return rval;4890}4891 4892int4893qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)4894{4895	int rval;4896	mbx_cmd_t mc;4897	mbx_cmd_t *mcp = &mc;4898	int len;4899	uint16_t dwlen;4900	uint8_t *str;4901	dma_addr_t str_dma;4902	struct qla_hw_data *ha = vha->hw;4903 4904	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||4905	    IS_P3P_TYPE(ha))4906		return QLA_FUNCTION_FAILED;4907 4908	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,4909	    "Entered %s.\n", __func__);4910 4911	str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);4912	if (!str) {4913		ql_log(ql_log_warn, vha, 0x117f,4914		    "Failed to allocate driver version param.\n");4915		return QLA_MEMORY_ALLOC_FAILED;4916	}4917 4918	memcpy(str, "\x7\x3\x11\x0", 4);4919	dwlen = str[0];4920	len = dwlen * 4 - 4;4921	memset(str + 4, 0, len);4922	if (len > strlen(version))4923		len = strlen(version);4924	memcpy(str + 4, version, len);4925 4926	mcp->mb[0] = MBC_SET_RNID_PARAMS;4927	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;4928	mcp->mb[2] = MSW(LSD(str_dma));4929	mcp->mb[3] = LSW(LSD(str_dma));4930	mcp->mb[6] = MSW(MSD(str_dma));4931	mcp->mb[7] = LSW(MSD(str_dma));4932	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;4933	mcp->in_mb = MBX_1|MBX_0;4934	mcp->tov = MBX_TOV_SECONDS;4935	mcp->flags = 0;4936	rval = qla2x00_mailbox_command(vha, mcp);4937 4938	if (rval != QLA_SUCCESS) {4939		ql_dbg(ql_dbg_mbx, vha, 0x1180,4940		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);4941	} else {4942		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,4943		    "Done %s.\n", __func__);4944	}4945 4946	dma_pool_free(ha->s_dma_pool, str, str_dma);4947 4948	return rval;4949}4950 4951int4952qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,4953			     void *buf, uint16_t bufsiz)4954{4955	int rval, i;4956	mbx_cmd_t mc;4957	mbx_cmd_t *mcp = &mc;4958	uint32_t	*bp;4959 4960	if (!IS_FWI2_CAPABLE(vha->hw))4961		return QLA_FUNCTION_FAILED;4962 4963	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,4964	    "Entered %s.\n", __func__);4965 4966	mcp->mb[0] = MBC_GET_RNID_PARAMS;4967	mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8;4968	mcp->mb[2] = MSW(buf_dma);4969	mcp->mb[3] = LSW(buf_dma);4970	mcp->mb[6] = MSW(MSD(buf_dma));4971	mcp->mb[7] = LSW(MSD(buf_dma));4972	mcp->mb[8] = bufsiz/4;4973	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;4974	mcp->in_mb = MBX_1|MBX_0;4975	mcp->tov = MBX_TOV_SECONDS;4976	mcp->flags = 0;4977	rval = qla2x00_mailbox_command(vha, mcp);4978 4979	if (rval != QLA_SUCCESS) {4980		ql_dbg(ql_dbg_mbx, vha, 0x115a,4981		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);4982	} else {4983		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,4984		    "Done %s.\n", __func__);4985		bp = (uint32_t *) buf;4986		for (i = 0; i < (bufsiz-4)/4; i++, bp++)4987			*bp = le32_to_cpu((__force __le32)*bp);4988	}4989 4990	return rval;4991}4992 4993#define PUREX_CMD_COUNT	44994int4995qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)4996{4997	int rval;4998	mbx_cmd_t mc;4999	mbx_cmd_t *mcp = &mc;5000	uint8_t *els_cmd_map;5001	uint8_t active_cnt = 0;5002	dma_addr_t els_cmd_map_dma;5003	uint8_t cmd_opcode[PUREX_CMD_COUNT];5004	uint8_t i, index, purex_bit;5005	struct qla_hw_data *ha = vha->hw;5006 5007	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&5008	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))5009		return QLA_SUCCESS;5010 5011	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,5012	    "Entered %s.\n", __func__);5013 5014	els_cmd_map = dma_alloc_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE,5015	    &els_cmd_map_dma, GFP_KERNEL);5016	if (!els_cmd_map) {5017		ql_log(ql_log_warn, vha, 0x7101,5018		    "Failed to allocate RDP els command param.\n");5019		return QLA_MEMORY_ALLOC_FAILED;5020	}5021 5022	/* List of Purex ELS */5023	if (ql2xrdpenable) {5024		cmd_opcode[active_cnt] = ELS_RDP;5025		active_cnt++;5026	}5027	if (ha->flags.scm_supported_f) {5028		cmd_opcode[active_cnt] = ELS_FPIN;5029		active_cnt++;5030	}5031	if (ha->flags.edif_enabled) {5032		cmd_opcode[active_cnt] = ELS_AUTH_ELS;5033		active_cnt++;5034	}5035 5036	for (i = 0; i < active_cnt; i++) {5037		index = cmd_opcode[i] / 8;5038		purex_bit = cmd_opcode[i] % 8;5039		els_cmd_map[index] |= 1 << purex_bit;5040	}5041 5042	mcp->mb[0] = MBC_SET_RNID_PARAMS;5043	mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;5044	mcp->mb[2] = MSW(LSD(els_cmd_map_dma));5045	mcp->mb[3] = LSW(LSD(els_cmd_map_dma));5046	mcp->mb[6] = MSW(MSD(els_cmd_map_dma));5047	mcp->mb[7] = LSW(MSD(els_cmd_map_dma));5048	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;5049	mcp->in_mb = MBX_1|MBX_0;5050	mcp->tov = MBX_TOV_SECONDS;5051	mcp->flags = MBX_DMA_OUT;5052	mcp->buf_size = ELS_CMD_MAP_SIZE;5053	rval = qla2x00_mailbox_command(vha, mcp);5054 5055	if (rval != QLA_SUCCESS) {5056		ql_dbg(ql_dbg_mbx, vha, 0x118d,5057		    "Failed=%x (%x,%x).\n", rval, mcp->mb[0], mcp->mb[1]);5058	} else {5059		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,5060		    "Done %s.\n", __func__);5061	}5062 5063	dma_free_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE,5064	   els_cmd_map, els_cmd_map_dma);5065 5066	return rval;5067}5068 5069static int5070qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)5071{5072	int rval;5073	mbx_cmd_t mc;5074	mbx_cmd_t *mcp = &mc;5075 5076	if (!IS_FWI2_CAPABLE(vha->hw))5077		return QLA_FUNCTION_FAILED;5078 5079	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,5080	    "Entered %s.\n", __func__);5081 5082	mcp->mb[0] = MBC_GET_RNID_PARAMS;5083	mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;5084	mcp->out_mb = MBX_1|MBX_0;5085	mcp->in_mb = MBX_1|MBX_0;5086	mcp->tov = MBX_TOV_SECONDS;5087	mcp->flags = 0;5088	rval = qla2x00_mailbox_command(vha, mcp);5089	*temp = mcp->mb[1];5090 5091	if (rval != QLA_SUCCESS) {5092		ql_dbg(ql_dbg_mbx, vha, 0x115a,5093		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);5094	} else {5095		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,5096		    "Done %s.\n", __func__);5097	}5098 5099	return rval;5100}5101 5102int5103qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,5104	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)5105{5106	int rval;5107	mbx_cmd_t mc;5108	mbx_cmd_t *mcp = &mc;5109	struct qla_hw_data *ha = vha->hw;5110 5111	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,5112	    "Entered %s.\n", __func__);5113 5114	if (!IS_FWI2_CAPABLE(ha))5115		return QLA_FUNCTION_FAILED;5116 5117	if (len == 1)5118		opt |= BIT_0;5119 5120	mcp->mb[0] = MBC_READ_SFP;5121	mcp->mb[1] = dev;5122	mcp->mb[2] = MSW(LSD(sfp_dma));5123	mcp->mb[3] = LSW(LSD(sfp_dma));5124	mcp->mb[6] = MSW(MSD(sfp_dma));5125	mcp->mb[7] = LSW(MSD(sfp_dma));5126	mcp->mb[8] = len;5127	mcp->mb[9] = off;5128	mcp->mb[10] = opt;5129	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;5130	mcp->in_mb = MBX_1|MBX_0;5131	mcp->tov = MBX_TOV_SECONDS;5132	mcp->flags = 0;5133	rval = qla2x00_mailbox_command(vha, mcp);5134 5135	if (opt & BIT_0)5136		*sfp = mcp->mb[1];5137 5138	if (rval != QLA_SUCCESS) {5139		ql_dbg(ql_dbg_mbx, vha, 0x10e9,5140		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5141		if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) {5142			/* sfp is not there */5143			rval = QLA_INTERFACE_ERROR;5144		}5145	} else {5146		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,5147		    "Done %s.\n", __func__);5148	}5149 5150	return rval;5151}5152 5153int5154qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,5155	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)5156{5157	int rval;5158	mbx_cmd_t mc;5159	mbx_cmd_t *mcp = &mc;5160	struct qla_hw_data *ha = vha->hw;5161 5162	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,5163	    "Entered %s.\n", __func__);5164 5165	if (!IS_FWI2_CAPABLE(ha))5166		return QLA_FUNCTION_FAILED;5167 5168	if (len == 1)5169		opt |= BIT_0;5170 5171	if (opt & BIT_0)5172		len = *sfp;5173 5174	mcp->mb[0] = MBC_WRITE_SFP;5175	mcp->mb[1] = dev;5176	mcp->mb[2] = MSW(LSD(sfp_dma));5177	mcp->mb[3] = LSW(LSD(sfp_dma));5178	mcp->mb[6] = MSW(MSD(sfp_dma));5179	mcp->mb[7] = LSW(MSD(sfp_dma));5180	mcp->mb[8] = len;5181	mcp->mb[9] = off;5182	mcp->mb[10] = opt;5183	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;5184	mcp->in_mb = MBX_1|MBX_0;5185	mcp->tov = MBX_TOV_SECONDS;5186	mcp->flags = 0;5187	rval = qla2x00_mailbox_command(vha, mcp);5188 5189	if (rval != QLA_SUCCESS) {5190		ql_dbg(ql_dbg_mbx, vha, 0x10ec,5191		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5192	} else {5193		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,5194		    "Done %s.\n", __func__);5195	}5196 5197	return rval;5198}5199 5200int5201qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,5202    uint16_t size_in_bytes, uint16_t *actual_size)5203{5204	int rval;5205	mbx_cmd_t mc;5206	mbx_cmd_t *mcp = &mc;5207 5208	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,5209	    "Entered %s.\n", __func__);5210 5211	if (!IS_CNA_CAPABLE(vha->hw))5212		return QLA_FUNCTION_FAILED;5213 5214	mcp->mb[0] = MBC_GET_XGMAC_STATS;5215	mcp->mb[2] = MSW(stats_dma);5216	mcp->mb[3] = LSW(stats_dma);5217	mcp->mb[6] = MSW(MSD(stats_dma));5218	mcp->mb[7] = LSW(MSD(stats_dma));5219	mcp->mb[8] = size_in_bytes >> 2;5220	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;5221	mcp->in_mb = MBX_2|MBX_1|MBX_0;5222	mcp->tov = MBX_TOV_SECONDS;5223	mcp->flags = 0;5224	rval = qla2x00_mailbox_command(vha, mcp);5225 5226	if (rval != QLA_SUCCESS) {5227		ql_dbg(ql_dbg_mbx, vha, 0x10ef,5228		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",5229		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);5230	} else {5231		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,5232		    "Done %s.\n", __func__);5233 5234 5235		*actual_size = mcp->mb[2] << 2;5236	}5237 5238	return rval;5239}5240 5241int5242qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,5243    uint16_t size)5244{5245	int rval;5246	mbx_cmd_t mc;5247	mbx_cmd_t *mcp = &mc;5248 5249	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,5250	    "Entered %s.\n", __func__);5251 5252	if (!IS_CNA_CAPABLE(vha->hw))5253		return QLA_FUNCTION_FAILED;5254 5255	mcp->mb[0] = MBC_GET_DCBX_PARAMS;5256	mcp->mb[1] = 0;5257	mcp->mb[2] = MSW(tlv_dma);5258	mcp->mb[3] = LSW(tlv_dma);5259	mcp->mb[6] = MSW(MSD(tlv_dma));5260	mcp->mb[7] = LSW(MSD(tlv_dma));5261	mcp->mb[8] = size;5262	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;5263	mcp->in_mb = MBX_2|MBX_1|MBX_0;5264	mcp->tov = MBX_TOV_SECONDS;5265	mcp->flags = 0;5266	rval = qla2x00_mailbox_command(vha, mcp);5267 5268	if (rval != QLA_SUCCESS) {5269		ql_dbg(ql_dbg_mbx, vha, 0x10f2,5270		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",5271		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);5272	} else {5273		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,5274		    "Done %s.\n", __func__);5275	}5276 5277	return rval;5278}5279 5280int5281qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)5282{5283	int rval;5284	mbx_cmd_t mc;5285	mbx_cmd_t *mcp = &mc;5286 5287	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,5288	    "Entered %s.\n", __func__);5289 5290	if (!IS_FWI2_CAPABLE(vha->hw))5291		return QLA_FUNCTION_FAILED;5292 5293	mcp->mb[0] = MBC_READ_RAM_EXTENDED;5294	mcp->mb[1] = LSW(risc_addr);5295	mcp->mb[8] = MSW(risc_addr);5296	mcp->out_mb = MBX_8|MBX_1|MBX_0;5297	mcp->in_mb = MBX_3|MBX_2|MBX_0;5298	mcp->tov = MBX_TOV_SECONDS;5299	mcp->flags = 0;5300	rval = qla2x00_mailbox_command(vha, mcp);5301	if (rval != QLA_SUCCESS) {5302		ql_dbg(ql_dbg_mbx, vha, 0x10f5,5303		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5304	} else {5305		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,5306		    "Done %s.\n", __func__);5307		*data = mcp->mb[3] << 16 | mcp->mb[2];5308	}5309 5310	return rval;5311}5312 5313int5314qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,5315	uint16_t *mresp)5316{5317	int rval;5318	mbx_cmd_t mc;5319	mbx_cmd_t *mcp = &mc;5320 5321	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,5322	    "Entered %s.\n", __func__);5323 5324	memset(mcp->mb, 0 , sizeof(mcp->mb));5325	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;5326	mcp->mb[1] = mreq->options | BIT_6;	// BIT_6 specifies 64 bit addressing5327 5328	/* transfer count */5329	mcp->mb[10] = LSW(mreq->transfer_size);5330	mcp->mb[11] = MSW(mreq->transfer_size);5331 5332	/* send data address */5333	mcp->mb[14] = LSW(mreq->send_dma);5334	mcp->mb[15] = MSW(mreq->send_dma);5335	mcp->mb[20] = LSW(MSD(mreq->send_dma));5336	mcp->mb[21] = MSW(MSD(mreq->send_dma));5337 5338	/* receive data address */5339	mcp->mb[16] = LSW(mreq->rcv_dma);5340	mcp->mb[17] = MSW(mreq->rcv_dma);5341	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));5342	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));5343 5344	/* Iteration count */5345	mcp->mb[18] = LSW(mreq->iteration_count);5346	mcp->mb[19] = MSW(mreq->iteration_count);5347 5348	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|5349	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;5350	if (IS_CNA_CAPABLE(vha->hw))5351		mcp->out_mb |= MBX_2;5352	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;5353 5354	mcp->buf_size = mreq->transfer_size;5355	mcp->tov = MBX_TOV_SECONDS;5356	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;5357 5358	rval = qla2x00_mailbox_command(vha, mcp);5359 5360	if (rval != QLA_SUCCESS) {5361		ql_dbg(ql_dbg_mbx, vha, 0x10f8,5362		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "5363		    "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],5364		    mcp->mb[3], mcp->mb[18], mcp->mb[19]);5365	} else {5366		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,5367		    "Done %s.\n", __func__);5368	}5369 5370	/* Copy mailbox information */5371	memcpy( mresp, mcp->mb, 64);5372	return rval;5373}5374 5375int5376qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,5377	uint16_t *mresp)5378{5379	int rval;5380	mbx_cmd_t mc;5381	mbx_cmd_t *mcp = &mc;5382	struct qla_hw_data *ha = vha->hw;5383 5384	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,5385	    "Entered %s.\n", __func__);5386 5387	memset(mcp->mb, 0 , sizeof(mcp->mb));5388	mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;5389	/* BIT_6 specifies 64bit address */5390	mcp->mb[1] = mreq->options | BIT_15 | BIT_6;5391	if (IS_CNA_CAPABLE(ha)) {5392		mcp->mb[2] = vha->fcoe_fcf_idx;5393	}5394	mcp->mb[16] = LSW(mreq->rcv_dma);5395	mcp->mb[17] = MSW(mreq->rcv_dma);5396	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));5397	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));5398 5399	mcp->mb[10] = LSW(mreq->transfer_size);5400 5401	mcp->mb[14] = LSW(mreq->send_dma);5402	mcp->mb[15] = MSW(mreq->send_dma);5403	mcp->mb[20] = LSW(MSD(mreq->send_dma));5404	mcp->mb[21] = MSW(MSD(mreq->send_dma));5405 5406	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|5407	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;5408	if (IS_CNA_CAPABLE(ha))5409		mcp->out_mb |= MBX_2;5410 5411	mcp->in_mb = MBX_0;5412	if (IS_CNA_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||5413	    IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))5414		mcp->in_mb |= MBX_1;5415	if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||5416	    IS_QLA28XX(ha))5417		mcp->in_mb |= MBX_3;5418 5419	mcp->tov = MBX_TOV_SECONDS;5420	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;5421	mcp->buf_size = mreq->transfer_size;5422 5423	rval = qla2x00_mailbox_command(vha, mcp);5424 5425	if (rval != QLA_SUCCESS) {5426		ql_dbg(ql_dbg_mbx, vha, 0x10fb,5427		    "Failed=%x mb[0]=%x mb[1]=%x.\n",5428		    rval, mcp->mb[0], mcp->mb[1]);5429	} else {5430		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,5431		    "Done %s.\n", __func__);5432	}5433 5434	/* Copy mailbox information */5435	memcpy(mresp, mcp->mb, 64);5436	return rval;5437}5438 5439int5440qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)5441{5442	int rval;5443	mbx_cmd_t mc;5444	mbx_cmd_t *mcp = &mc;5445 5446	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,5447	    "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);5448 5449	mcp->mb[0] = MBC_ISP84XX_RESET;5450	mcp->mb[1] = enable_diagnostic;5451	mcp->out_mb = MBX_1|MBX_0;5452	mcp->in_mb = MBX_1|MBX_0;5453	mcp->tov = MBX_TOV_SECONDS;5454	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;5455	rval = qla2x00_mailbox_command(vha, mcp);5456 5457	if (rval != QLA_SUCCESS)5458		ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);5459	else5460		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,5461		    "Done %s.\n", __func__);5462 5463	return rval;5464}5465 5466int5467qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)5468{5469	int rval;5470	mbx_cmd_t mc;5471	mbx_cmd_t *mcp = &mc;5472 5473	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,5474	    "Entered %s.\n", __func__);5475 5476	if (!IS_FWI2_CAPABLE(vha->hw))5477		return QLA_FUNCTION_FAILED;5478 5479	mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;5480	mcp->mb[1] = LSW(risc_addr);5481	mcp->mb[2] = LSW(data);5482	mcp->mb[3] = MSW(data);5483	mcp->mb[8] = MSW(risc_addr);5484	mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;5485	mcp->in_mb = MBX_1|MBX_0;5486	mcp->tov = MBX_TOV_SECONDS;5487	mcp->flags = 0;5488	rval = qla2x00_mailbox_command(vha, mcp);5489	if (rval != QLA_SUCCESS) {5490		ql_dbg(ql_dbg_mbx, vha, 0x1101,5491		    "Failed=%x mb[0]=%x mb[1]=%x.\n",5492		    rval, mcp->mb[0], mcp->mb[1]);5493	} else {5494		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,5495		    "Done %s.\n", __func__);5496	}5497 5498	return rval;5499}5500 5501int5502qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)5503{5504	int rval;5505	uint32_t stat, timer;5506	uint16_t mb0 = 0;5507	struct qla_hw_data *ha = vha->hw;5508	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;5509 5510	rval = QLA_SUCCESS;5511 5512	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,5513	    "Entered %s.\n", __func__);5514 5515	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);5516 5517	/* Write the MBC data to the registers */5518	wrt_reg_word(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);5519	wrt_reg_word(&reg->mailbox1, mb[0]);5520	wrt_reg_word(&reg->mailbox2, mb[1]);5521	wrt_reg_word(&reg->mailbox3, mb[2]);5522	wrt_reg_word(&reg->mailbox4, mb[3]);5523 5524	wrt_reg_dword(&reg->hccr, HCCRX_SET_HOST_INT);5525 5526	/* Poll for MBC interrupt */5527	for (timer = 6000000; timer; timer--) {5528		/* Check for pending interrupts. */5529		stat = rd_reg_dword(&reg->host_status);5530		if (stat & HSRX_RISC_INT) {5531			stat &= 0xff;5532 5533			if (stat == 0x1 || stat == 0x2 ||5534			    stat == 0x10 || stat == 0x11) {5535				set_bit(MBX_INTERRUPT,5536				    &ha->mbx_cmd_flags);5537				mb0 = rd_reg_word(&reg->mailbox0);5538				wrt_reg_dword(&reg->hccr,5539				    HCCRX_CLR_RISC_INT);5540				rd_reg_dword(&reg->hccr);5541				break;5542			}5543		}5544		udelay(5);5545	}5546 5547	if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))5548		rval = mb0 & MBS_MASK;5549	else5550		rval = QLA_FUNCTION_FAILED;5551 5552	if (rval != QLA_SUCCESS) {5553		ql_dbg(ql_dbg_mbx, vha, 0x1104,5554		    "Failed=%x mb[0]=%x.\n", rval, mb[0]);5555	} else {5556		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,5557		    "Done %s.\n", __func__);5558	}5559 5560	return rval;5561}5562 5563/* Set the specified data rate */5564int5565qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode)5566{5567	int rval;5568	mbx_cmd_t mc;5569	mbx_cmd_t *mcp = &mc;5570	struct qla_hw_data *ha = vha->hw;5571	uint16_t val;5572 5573	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,5574	    "Entered %s speed:0x%x mode:0x%x.\n", __func__, ha->set_data_rate,5575	    mode);5576 5577	if (!IS_FWI2_CAPABLE(ha))5578		return QLA_FUNCTION_FAILED;5579 5580	memset(mcp, 0, sizeof(*mcp));5581	switch (ha->set_data_rate) {5582	case PORT_SPEED_AUTO:5583	case PORT_SPEED_4GB:5584	case PORT_SPEED_8GB:5585	case PORT_SPEED_16GB:5586	case PORT_SPEED_32GB:5587		val = ha->set_data_rate;5588		break;5589	default:5590		ql_log(ql_log_warn, vha, 0x1199,5591		    "Unrecognized speed setting:%d. Setting Autoneg\n",5592		    ha->set_data_rate);5593		val = ha->set_data_rate = PORT_SPEED_AUTO;5594		break;5595	}5596 5597	mcp->mb[0] = MBC_DATA_RATE;5598	mcp->mb[1] = mode;5599	mcp->mb[2] = val;5600 5601	mcp->out_mb = MBX_2|MBX_1|MBX_0;5602	mcp->in_mb = MBX_2|MBX_1|MBX_0;5603	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))5604		mcp->in_mb |= MBX_4|MBX_3;5605	mcp->tov = MBX_TOV_SECONDS;5606	mcp->flags = 0;5607	rval = qla2x00_mailbox_command(vha, mcp);5608	if (rval != QLA_SUCCESS) {5609		ql_dbg(ql_dbg_mbx, vha, 0x1107,5610		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5611	} else {5612		if (mcp->mb[1] != 0x7)5613			ql_dbg(ql_dbg_mbx, vha, 0x1179,5614				"Speed set:0x%x\n", mcp->mb[1]);5615 5616		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,5617		    "Done %s.\n", __func__);5618	}5619 5620	return rval;5621}5622 5623int5624qla2x00_get_data_rate(scsi_qla_host_t *vha)5625{5626	int rval;5627	mbx_cmd_t mc;5628	mbx_cmd_t *mcp = &mc;5629	struct qla_hw_data *ha = vha->hw;5630 5631	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,5632	    "Entered %s.\n", __func__);5633 5634	if (!IS_FWI2_CAPABLE(ha))5635		return QLA_FUNCTION_FAILED;5636 5637	mcp->mb[0] = MBC_DATA_RATE;5638	mcp->mb[1] = QLA_GET_DATA_RATE;5639	mcp->out_mb = MBX_1|MBX_0;5640	mcp->in_mb = MBX_2|MBX_1|MBX_0;5641	if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))5642		mcp->in_mb |= MBX_4|MBX_3;5643	mcp->tov = MBX_TOV_SECONDS;5644	mcp->flags = 0;5645	rval = qla2x00_mailbox_command(vha, mcp);5646	if (rval != QLA_SUCCESS) {5647		ql_dbg(ql_dbg_mbx, vha, 0x1107,5648		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5649	} else {5650		if (mcp->mb[1] != 0x7)5651			ha->link_data_rate = mcp->mb[1];5652 5653		if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {5654			if (mcp->mb[4] & BIT_0)5655				ql_log(ql_log_info, vha, 0x11a2,5656				    "FEC=enabled (data rate).\n");5657		}5658 5659		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,5660		    "Done %s.\n", __func__);5661		if (mcp->mb[1] != 0x7)5662			ha->link_data_rate = mcp->mb[1];5663	}5664 5665	return rval;5666}5667 5668int5669qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)5670{5671	int rval;5672	mbx_cmd_t mc;5673	mbx_cmd_t *mcp = &mc;5674	struct qla_hw_data *ha = vha->hw;5675 5676	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,5677	    "Entered %s.\n", __func__);5678 5679	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&5680	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))5681		return QLA_FUNCTION_FAILED;5682	mcp->mb[0] = MBC_GET_PORT_CONFIG;5683	mcp->out_mb = MBX_0;5684	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;5685	mcp->tov = MBX_TOV_SECONDS;5686	mcp->flags = 0;5687 5688	rval = qla2x00_mailbox_command(vha, mcp);5689 5690	if (rval != QLA_SUCCESS) {5691		ql_dbg(ql_dbg_mbx, vha, 0x110a,5692		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5693	} else {5694		/* Copy all bits to preserve original value */5695		memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);5696 5697		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,5698		    "Done %s.\n", __func__);5699	}5700	return rval;5701}5702 5703int5704qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)5705{5706	int rval;5707	mbx_cmd_t mc;5708	mbx_cmd_t *mcp = &mc;5709 5710	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,5711	    "Entered %s.\n", __func__);5712 5713	mcp->mb[0] = MBC_SET_PORT_CONFIG;5714	/* Copy all bits to preserve original setting */5715	memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);5716	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;5717	mcp->in_mb = MBX_0;5718	mcp->tov = MBX_TOV_SECONDS;5719	mcp->flags = 0;5720	rval = qla2x00_mailbox_command(vha, mcp);5721 5722	if (rval != QLA_SUCCESS) {5723		ql_dbg(ql_dbg_mbx, vha, 0x110d,5724		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5725	} else5726		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,5727		    "Done %s.\n", __func__);5728 5729	return rval;5730}5731 5732 5733int5734qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,5735		uint16_t *mb)5736{5737	int rval;5738	mbx_cmd_t mc;5739	mbx_cmd_t *mcp = &mc;5740	struct qla_hw_data *ha = vha->hw;5741 5742	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,5743	    "Entered %s.\n", __func__);5744 5745	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))5746		return QLA_FUNCTION_FAILED;5747 5748	mcp->mb[0] = MBC_PORT_PARAMS;5749	mcp->mb[1] = loop_id;5750	if (ha->flags.fcp_prio_enabled)5751		mcp->mb[2] = BIT_1;5752	else5753		mcp->mb[2] = BIT_2;5754	mcp->mb[4] = priority & 0xf;5755	mcp->mb[9] = vha->vp_idx;5756	mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;5757	mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;5758	mcp->tov = MBX_TOV_SECONDS;5759	mcp->flags = 0;5760	rval = qla2x00_mailbox_command(vha, mcp);5761	if (mb != NULL) {5762		mb[0] = mcp->mb[0];5763		mb[1] = mcp->mb[1];5764		mb[3] = mcp->mb[3];5765		mb[4] = mcp->mb[4];5766	}5767 5768	if (rval != QLA_SUCCESS) {5769		ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);5770	} else {5771		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,5772		    "Done %s.\n", __func__);5773	}5774 5775	return rval;5776}5777 5778int5779qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)5780{5781	int rval = QLA_FUNCTION_FAILED;5782	struct qla_hw_data *ha = vha->hw;5783	uint8_t byte;5784 5785	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {5786		ql_dbg(ql_dbg_mbx, vha, 0x1150,5787		    "Thermal not supported by this card.\n");5788		return rval;5789	}5790 5791	if (IS_QLA25XX(ha)) {5792		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&5793		    ha->pdev->subsystem_device == 0x0175) {5794			rval = qla2x00_read_sfp(vha, 0, &byte,5795			    0x98, 0x1, 1, BIT_13|BIT_0);5796			*temp = byte;5797			return rval;5798		}5799		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&5800		    ha->pdev->subsystem_device == 0x338e) {5801			rval = qla2x00_read_sfp(vha, 0, &byte,5802			    0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);5803			*temp = byte;5804			return rval;5805		}5806		ql_dbg(ql_dbg_mbx, vha, 0x10c9,5807		    "Thermal not supported by this card.\n");5808		return rval;5809	}5810 5811	if (IS_QLA82XX(ha)) {5812		*temp = qla82xx_read_temperature(vha);5813		rval = QLA_SUCCESS;5814		return rval;5815	} else if (IS_QLA8044(ha)) {5816		*temp = qla8044_read_temperature(vha);5817		rval = QLA_SUCCESS;5818		return rval;5819	}5820 5821	rval = qla2x00_read_asic_temperature(vha, temp);5822	return rval;5823}5824 5825int5826qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)5827{5828	int rval;5829	struct qla_hw_data *ha = vha->hw;5830	mbx_cmd_t mc;5831	mbx_cmd_t *mcp = &mc;5832 5833	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,5834	    "Entered %s.\n", __func__);5835 5836	if (!IS_FWI2_CAPABLE(ha))5837		return QLA_FUNCTION_FAILED;5838 5839	memset(mcp, 0, sizeof(mbx_cmd_t));5840	mcp->mb[0] = MBC_TOGGLE_INTERRUPT;5841	mcp->mb[1] = 1;5842 5843	mcp->out_mb = MBX_1|MBX_0;5844	mcp->in_mb = MBX_0;5845	mcp->tov = MBX_TOV_SECONDS;5846	mcp->flags = 0;5847 5848	rval = qla2x00_mailbox_command(vha, mcp);5849	if (rval != QLA_SUCCESS) {5850		ql_dbg(ql_dbg_mbx, vha, 0x1016,5851		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5852	} else {5853		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,5854		    "Done %s.\n", __func__);5855	}5856 5857	return rval;5858}5859 5860int5861qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)5862{5863	int rval;5864	struct qla_hw_data *ha = vha->hw;5865	mbx_cmd_t mc;5866	mbx_cmd_t *mcp = &mc;5867 5868	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,5869	    "Entered %s.\n", __func__);5870 5871	if (!IS_P3P_TYPE(ha))5872		return QLA_FUNCTION_FAILED;5873 5874	memset(mcp, 0, sizeof(mbx_cmd_t));5875	mcp->mb[0] = MBC_TOGGLE_INTERRUPT;5876	mcp->mb[1] = 0;5877 5878	mcp->out_mb = MBX_1|MBX_0;5879	mcp->in_mb = MBX_0;5880	mcp->tov = MBX_TOV_SECONDS;5881	mcp->flags = 0;5882 5883	rval = qla2x00_mailbox_command(vha, mcp);5884	if (rval != QLA_SUCCESS) {5885		ql_dbg(ql_dbg_mbx, vha, 0x100c,5886		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);5887	} else {5888		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,5889		    "Done %s.\n", __func__);5890	}5891 5892	return rval;5893}5894 5895int5896qla82xx_md_get_template_size(scsi_qla_host_t *vha)5897{5898	struct qla_hw_data *ha = vha->hw;5899	mbx_cmd_t mc;5900	mbx_cmd_t *mcp = &mc;5901	int rval = QLA_FUNCTION_FAILED;5902 5903	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,5904	    "Entered %s.\n", __func__);5905 5906	memset(mcp->mb, 0 , sizeof(mcp->mb));5907	mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);5908	mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);5909	mcp->mb[2] = LSW(RQST_TMPLT_SIZE);5910	mcp->mb[3] = MSW(RQST_TMPLT_SIZE);5911 5912	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;5913	mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|5914	    MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;5915 5916	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;5917	mcp->tov = MBX_TOV_SECONDS;5918	rval = qla2x00_mailbox_command(vha, mcp);5919 5920	/* Always copy back return mailbox values. */5921	if (rval != QLA_SUCCESS) {5922		ql_dbg(ql_dbg_mbx, vha, 0x1120,5923		    "mailbox command FAILED=0x%x, subcode=%x.\n",5924		    (mcp->mb[1] << 16) | mcp->mb[0],5925		    (mcp->mb[3] << 16) | mcp->mb[2]);5926	} else {5927		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,5928		    "Done %s.\n", __func__);5929		ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);5930		if (!ha->md_template_size) {5931			ql_dbg(ql_dbg_mbx, vha, 0x1122,5932			    "Null template size obtained.\n");5933			rval = QLA_FUNCTION_FAILED;5934		}5935	}5936	return rval;5937}5938 5939int5940qla82xx_md_get_template(scsi_qla_host_t *vha)5941{5942	struct qla_hw_data *ha = vha->hw;5943	mbx_cmd_t mc;5944	mbx_cmd_t *mcp = &mc;5945	int rval = QLA_FUNCTION_FAILED;5946 5947	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,5948	    "Entered %s.\n", __func__);5949 5950	ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,5951	   ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);5952	if (!ha->md_tmplt_hdr) {5953		ql_log(ql_log_warn, vha, 0x1124,5954		    "Unable to allocate memory for Minidump template.\n");5955		return rval;5956	}5957 5958	memset(mcp->mb, 0 , sizeof(mcp->mb));5959	mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);5960	mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);5961	mcp->mb[2] = LSW(RQST_TMPLT);5962	mcp->mb[3] = MSW(RQST_TMPLT);5963	mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));5964	mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));5965	mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));5966	mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));5967	mcp->mb[8] = LSW(ha->md_template_size);5968	mcp->mb[9] = MSW(ha->md_template_size);5969 5970	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;5971	mcp->tov = MBX_TOV_SECONDS;5972	mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|5973	    MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;5974	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;5975	rval = qla2x00_mailbox_command(vha, mcp);5976 5977	if (rval != QLA_SUCCESS) {5978		ql_dbg(ql_dbg_mbx, vha, 0x1125,5979		    "mailbox command FAILED=0x%x, subcode=%x.\n",5980		    ((mcp->mb[1] << 16) | mcp->mb[0]),5981		    ((mcp->mb[3] << 16) | mcp->mb[2]));5982	} else5983		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,5984		    "Done %s.\n", __func__);5985	return rval;5986}5987 5988int5989qla8044_md_get_template(scsi_qla_host_t *vha)5990{5991	struct qla_hw_data *ha = vha->hw;5992	mbx_cmd_t mc;5993	mbx_cmd_t *mcp = &mc;5994	int rval = QLA_FUNCTION_FAILED;5995	int offset = 0, size = MINIDUMP_SIZE_36K;5996 5997	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,5998	    "Entered %s.\n", __func__);5999 6000	ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,6001	   ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);6002	if (!ha->md_tmplt_hdr) {6003		ql_log(ql_log_warn, vha, 0xb11b,6004		    "Unable to allocate memory for Minidump template.\n");6005		return rval;6006	}6007 6008	memset(mcp->mb, 0 , sizeof(mcp->mb));6009	while (offset < ha->md_template_size) {6010		mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);6011		mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);6012		mcp->mb[2] = LSW(RQST_TMPLT);6013		mcp->mb[3] = MSW(RQST_TMPLT);6014		mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));6015		mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));6016		mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));6017		mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));6018		mcp->mb[8] = LSW(size);6019		mcp->mb[9] = MSW(size);6020		mcp->mb[10] = offset & 0x0000FFFF;6021		mcp->mb[11] = offset & 0xFFFF0000;6022		mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;6023		mcp->tov = MBX_TOV_SECONDS;6024		mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|6025			MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;6026		mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;6027		rval = qla2x00_mailbox_command(vha, mcp);6028 6029		if (rval != QLA_SUCCESS) {6030			ql_dbg(ql_dbg_mbx, vha, 0xb11c,6031				"mailbox command FAILED=0x%x, subcode=%x.\n",6032				((mcp->mb[1] << 16) | mcp->mb[0]),6033				((mcp->mb[3] << 16) | mcp->mb[2]));6034			return rval;6035		} else6036			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,6037				"Done %s.\n", __func__);6038		offset = offset + size;6039	}6040	return rval;6041}6042 6043int6044qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)6045{6046	int rval;6047	struct qla_hw_data *ha = vha->hw;6048	mbx_cmd_t mc;6049	mbx_cmd_t *mcp = &mc;6050 6051	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))6052		return QLA_FUNCTION_FAILED;6053 6054	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,6055	    "Entered %s.\n", __func__);6056 6057	memset(mcp, 0, sizeof(mbx_cmd_t));6058	mcp->mb[0] = MBC_SET_LED_CONFIG;6059	mcp->mb[1] = led_cfg[0];6060	mcp->mb[2] = led_cfg[1];6061	if (IS_QLA8031(ha)) {6062		mcp->mb[3] = led_cfg[2];6063		mcp->mb[4] = led_cfg[3];6064		mcp->mb[5] = led_cfg[4];6065		mcp->mb[6] = led_cfg[5];6066	}6067 6068	mcp->out_mb = MBX_2|MBX_1|MBX_0;6069	if (IS_QLA8031(ha))6070		mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;6071	mcp->in_mb = MBX_0;6072	mcp->tov = MBX_TOV_SECONDS;6073	mcp->flags = 0;6074 6075	rval = qla2x00_mailbox_command(vha, mcp);6076	if (rval != QLA_SUCCESS) {6077		ql_dbg(ql_dbg_mbx, vha, 0x1134,6078		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6079	} else {6080		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,6081		    "Done %s.\n", __func__);6082	}6083 6084	return rval;6085}6086 6087int6088qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)6089{6090	int rval;6091	struct qla_hw_data *ha = vha->hw;6092	mbx_cmd_t mc;6093	mbx_cmd_t *mcp = &mc;6094 6095	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))6096		return QLA_FUNCTION_FAILED;6097 6098	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,6099	    "Entered %s.\n", __func__);6100 6101	memset(mcp, 0, sizeof(mbx_cmd_t));6102	mcp->mb[0] = MBC_GET_LED_CONFIG;6103 6104	mcp->out_mb = MBX_0;6105	mcp->in_mb = MBX_2|MBX_1|MBX_0;6106	if (IS_QLA8031(ha))6107		mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;6108	mcp->tov = MBX_TOV_SECONDS;6109	mcp->flags = 0;6110 6111	rval = qla2x00_mailbox_command(vha, mcp);6112	if (rval != QLA_SUCCESS) {6113		ql_dbg(ql_dbg_mbx, vha, 0x1137,6114		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6115	} else {6116		led_cfg[0] = mcp->mb[1];6117		led_cfg[1] = mcp->mb[2];6118		if (IS_QLA8031(ha)) {6119			led_cfg[2] = mcp->mb[3];6120			led_cfg[3] = mcp->mb[4];6121			led_cfg[4] = mcp->mb[5];6122			led_cfg[5] = mcp->mb[6];6123		}6124		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,6125		    "Done %s.\n", __func__);6126	}6127 6128	return rval;6129}6130 6131int6132qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)6133{6134	int rval;6135	struct qla_hw_data *ha = vha->hw;6136	mbx_cmd_t mc;6137	mbx_cmd_t *mcp = &mc;6138 6139	if (!IS_P3P_TYPE(ha))6140		return QLA_FUNCTION_FAILED;6141 6142	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,6143		"Entered %s.\n", __func__);6144 6145	memset(mcp, 0, sizeof(mbx_cmd_t));6146	mcp->mb[0] = MBC_SET_LED_CONFIG;6147	if (enable)6148		mcp->mb[7] = 0xE;6149	else6150		mcp->mb[7] = 0xD;6151 6152	mcp->out_mb = MBX_7|MBX_0;6153	mcp->in_mb = MBX_0;6154	mcp->tov = MBX_TOV_SECONDS;6155	mcp->flags = 0;6156 6157	rval = qla2x00_mailbox_command(vha, mcp);6158	if (rval != QLA_SUCCESS) {6159		ql_dbg(ql_dbg_mbx, vha, 0x1128,6160		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6161	} else {6162		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,6163		    "Done %s.\n", __func__);6164	}6165 6166	return rval;6167}6168 6169int6170qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)6171{6172	int rval;6173	struct qla_hw_data *ha = vha->hw;6174	mbx_cmd_t mc;6175	mbx_cmd_t *mcp = &mc;6176 6177	if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))6178		return QLA_FUNCTION_FAILED;6179 6180	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,6181	    "Entered %s.\n", __func__);6182 6183	mcp->mb[0] = MBC_WRITE_REMOTE_REG;6184	mcp->mb[1] = LSW(reg);6185	mcp->mb[2] = MSW(reg);6186	mcp->mb[3] = LSW(data);6187	mcp->mb[4] = MSW(data);6188	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;6189 6190	mcp->in_mb = MBX_1|MBX_0;6191	mcp->tov = MBX_TOV_SECONDS;6192	mcp->flags = 0;6193	rval = qla2x00_mailbox_command(vha, mcp);6194 6195	if (rval != QLA_SUCCESS) {6196		ql_dbg(ql_dbg_mbx, vha, 0x1131,6197		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6198	} else {6199		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,6200		    "Done %s.\n", __func__);6201	}6202 6203	return rval;6204}6205 6206int6207qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)6208{6209	int rval;6210	struct qla_hw_data *ha = vha->hw;6211	mbx_cmd_t mc;6212	mbx_cmd_t *mcp = &mc;6213 6214	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {6215		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,6216		    "Implicit LOGO Unsupported.\n");6217		return QLA_FUNCTION_FAILED;6218	}6219 6220 6221	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,6222	    "Entering %s.\n",  __func__);6223 6224	/* Perform Implicit LOGO. */6225	mcp->mb[0] = MBC_PORT_LOGOUT;6226	mcp->mb[1] = fcport->loop_id;6227	mcp->mb[10] = BIT_15;6228	mcp->out_mb = MBX_10|MBX_1|MBX_0;6229	mcp->in_mb = MBX_0;6230	mcp->tov = MBX_TOV_SECONDS;6231	mcp->flags = 0;6232	rval = qla2x00_mailbox_command(vha, mcp);6233	if (rval != QLA_SUCCESS)6234		ql_dbg(ql_dbg_mbx, vha, 0x113d,6235		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6236	else6237		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,6238		    "Done %s.\n", __func__);6239 6240	return rval;6241}6242 6243int6244qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)6245{6246	int rval;6247	mbx_cmd_t mc;6248	mbx_cmd_t *mcp = &mc;6249	struct qla_hw_data *ha = vha->hw;6250	unsigned long retry_max_time = jiffies + (2 * HZ);6251 6252	if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))6253		return QLA_FUNCTION_FAILED;6254 6255	ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);6256 6257retry_rd_reg:6258	mcp->mb[0] = MBC_READ_REMOTE_REG;6259	mcp->mb[1] = LSW(reg);6260	mcp->mb[2] = MSW(reg);6261	mcp->out_mb = MBX_2|MBX_1|MBX_0;6262	mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;6263	mcp->tov = MBX_TOV_SECONDS;6264	mcp->flags = 0;6265	rval = qla2x00_mailbox_command(vha, mcp);6266 6267	if (rval != QLA_SUCCESS) {6268		ql_dbg(ql_dbg_mbx, vha, 0x114c,6269		    "Failed=%x mb[0]=%x mb[1]=%x.\n",6270		    rval, mcp->mb[0], mcp->mb[1]);6271	} else {6272		*data = (mcp->mb[3] | (mcp->mb[4] << 16));6273		if (*data == QLA8XXX_BAD_VALUE) {6274			/*6275			 * During soft-reset CAMRAM register reads might6276			 * return 0xbad0bad0. So retry for MAX of 2 sec6277			 * while reading camram registers.6278			 */6279			if (time_after(jiffies, retry_max_time)) {6280				ql_dbg(ql_dbg_mbx, vha, 0x1141,6281				    "Failure to read CAMRAM register. "6282				    "data=0x%x.\n", *data);6283				return QLA_FUNCTION_FAILED;6284			}6285			msleep(100);6286			goto retry_rd_reg;6287		}6288		ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);6289	}6290 6291	return rval;6292}6293 6294int6295qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)6296{6297	int rval;6298	mbx_cmd_t mc;6299	mbx_cmd_t *mcp = &mc;6300	struct qla_hw_data *ha = vha->hw;6301 6302	if (!IS_QLA83XX(ha))6303		return QLA_FUNCTION_FAILED;6304 6305	ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);6306 6307	mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;6308	mcp->out_mb = MBX_0;6309	mcp->in_mb = MBX_1|MBX_0;6310	mcp->tov = MBX_TOV_SECONDS;6311	mcp->flags = 0;6312	rval = qla2x00_mailbox_command(vha, mcp);6313 6314	if (rval != QLA_SUCCESS) {6315		ql_dbg(ql_dbg_mbx, vha, 0x1144,6316		    "Failed=%x mb[0]=%x mb[1]=%x.\n",6317		    rval, mcp->mb[0], mcp->mb[1]);6318		qla2xxx_dump_fw(vha);6319	} else {6320		ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);6321	}6322 6323	return rval;6324}6325 6326int6327qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,6328	uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)6329{6330	int rval;6331	mbx_cmd_t mc;6332	mbx_cmd_t *mcp = &mc;6333	uint8_t subcode = (uint8_t)options;6334	struct qla_hw_data *ha = vha->hw;6335 6336	if (!IS_QLA8031(ha))6337		return QLA_FUNCTION_FAILED;6338 6339	ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);6340 6341	mcp->mb[0] = MBC_SET_ACCESS_CONTROL;6342	mcp->mb[1] = options;6343	mcp->out_mb = MBX_1|MBX_0;6344	if (subcode & BIT_2) {6345		mcp->mb[2] = LSW(start_addr);6346		mcp->mb[3] = MSW(start_addr);6347		mcp->mb[4] = LSW(end_addr);6348		mcp->mb[5] = MSW(end_addr);6349		mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;6350	}6351	mcp->in_mb = MBX_2|MBX_1|MBX_0;6352	if (!(subcode & (BIT_2 | BIT_5)))6353		mcp->in_mb |= MBX_4|MBX_3;6354	mcp->tov = MBX_TOV_SECONDS;6355	mcp->flags = 0;6356	rval = qla2x00_mailbox_command(vha, mcp);6357 6358	if (rval != QLA_SUCCESS) {6359		ql_dbg(ql_dbg_mbx, vha, 0x1147,6360		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",6361		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],6362		    mcp->mb[4]);6363		qla2xxx_dump_fw(vha);6364	} else {6365		if (subcode & BIT_5)6366			*sector_size = mcp->mb[1];6367		else if (subcode & (BIT_6 | BIT_7)) {6368			ql_dbg(ql_dbg_mbx, vha, 0x1148,6369			    "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);6370		} else if (subcode & (BIT_3 | BIT_4)) {6371			ql_dbg(ql_dbg_mbx, vha, 0x1149,6372			    "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);6373		}6374		ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);6375	}6376 6377	return rval;6378}6379 6380int6381qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,6382	uint32_t size)6383{6384	int rval;6385	mbx_cmd_t mc;6386	mbx_cmd_t *mcp = &mc;6387 6388	if (!IS_MCTP_CAPABLE(vha->hw))6389		return QLA_FUNCTION_FAILED;6390 6391	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,6392	    "Entered %s.\n", __func__);6393 6394	mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;6395	mcp->mb[1] = LSW(addr);6396	mcp->mb[2] = MSW(req_dma);6397	mcp->mb[3] = LSW(req_dma);6398	mcp->mb[4] = MSW(size);6399	mcp->mb[5] = LSW(size);6400	mcp->mb[6] = MSW(MSD(req_dma));6401	mcp->mb[7] = LSW(MSD(req_dma));6402	mcp->mb[8] = MSW(addr);6403	/* Setting RAM ID to valid */6404	/* For MCTP RAM ID is 0x40 */6405	mcp->mb[10] = BIT_7 | 0x40;6406 6407	mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|6408	    MBX_0;6409 6410	mcp->in_mb = MBX_0;6411	mcp->tov = MBX_TOV_SECONDS;6412	mcp->flags = 0;6413	rval = qla2x00_mailbox_command(vha, mcp);6414 6415	if (rval != QLA_SUCCESS) {6416		ql_dbg(ql_dbg_mbx, vha, 0x114e,6417		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6418	} else {6419		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,6420		    "Done %s.\n", __func__);6421	}6422 6423	return rval;6424}6425 6426int6427qla26xx_dport_diagnostics(scsi_qla_host_t *vha,6428	void *dd_buf, uint size, uint options)6429{6430	int rval;6431	mbx_cmd_t mc;6432	mbx_cmd_t *mcp = &mc;6433	dma_addr_t dd_dma;6434 6435	if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&6436	    !IS_QLA28XX(vha->hw))6437		return QLA_FUNCTION_FAILED;6438 6439	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,6440	    "Entered %s.\n", __func__);6441 6442	dd_dma = dma_map_single(&vha->hw->pdev->dev,6443	    dd_buf, size, DMA_FROM_DEVICE);6444	if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {6445		ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");6446		return QLA_MEMORY_ALLOC_FAILED;6447	}6448 6449	memset(dd_buf, 0, size);6450 6451	mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;6452	mcp->mb[1] = options;6453	mcp->mb[2] = MSW(LSD(dd_dma));6454	mcp->mb[3] = LSW(LSD(dd_dma));6455	mcp->mb[6] = MSW(MSD(dd_dma));6456	mcp->mb[7] = LSW(MSD(dd_dma));6457	mcp->mb[8] = size;6458	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;6459	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;6460	mcp->buf_size = size;6461	mcp->flags = MBX_DMA_IN;6462	mcp->tov = MBX_TOV_SECONDS * 4;6463	rval = qla2x00_mailbox_command(vha, mcp);6464 6465	if (rval != QLA_SUCCESS) {6466		ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);6467	} else {6468		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,6469		    "Done %s.\n", __func__);6470	}6471 6472	dma_unmap_single(&vha->hw->pdev->dev, dd_dma,6473	    size, DMA_FROM_DEVICE);6474 6475	return rval;6476}6477 6478int6479qla26xx_dport_diagnostics_v2(scsi_qla_host_t *vha,6480			     struct qla_dport_diag_v2 *dd,  mbx_cmd_t *mcp)6481{6482	int rval;6483	dma_addr_t dd_dma;6484	uint size = sizeof(dd->buf);6485	uint16_t options = dd->options;6486 6487	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,6488	       "Entered %s.\n", __func__);6489 6490	dd_dma = dma_map_single(&vha->hw->pdev->dev,6491				dd->buf, size, DMA_FROM_DEVICE);6492	if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {6493		ql_log(ql_log_warn, vha, 0x1194,6494		       "Failed to map dma buffer.\n");6495		return QLA_MEMORY_ALLOC_FAILED;6496	}6497 6498	memset(dd->buf, 0, size);6499 6500	mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;6501	mcp->mb[1] = options;6502	mcp->mb[2] = MSW(LSD(dd_dma));6503	mcp->mb[3] = LSW(LSD(dd_dma));6504	mcp->mb[6] = MSW(MSD(dd_dma));6505	mcp->mb[7] = LSW(MSD(dd_dma));6506	mcp->mb[8] = size;6507	mcp->out_mb = MBX_8 | MBX_7 | MBX_6 | MBX_3 | MBX_2 | MBX_1 | MBX_0;6508	mcp->in_mb = MBX_3 | MBX_2 | MBX_1 | MBX_0;6509	mcp->buf_size = size;6510	mcp->flags = MBX_DMA_IN;6511	mcp->tov = MBX_TOV_SECONDS * 4;6512	rval = qla2x00_mailbox_command(vha, mcp);6513 6514	if (rval != QLA_SUCCESS) {6515		ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);6516	} else {6517		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,6518		       "Done %s.\n", __func__);6519	}6520 6521	dma_unmap_single(&vha->hw->pdev->dev, dd_dma, size, DMA_FROM_DEVICE);6522 6523	return rval;6524}6525 6526static void qla2x00_async_mb_sp_done(srb_t *sp, int res)6527{6528	sp->u.iocb_cmd.u.mbx.rc = res;6529 6530	complete(&sp->u.iocb_cmd.u.mbx.comp);6531	/* don't free sp here. Let the caller do the free */6532}6533 6534/*6535 * This mailbox uses the iocb interface to send MB command.6536 * This allows non-critial (non chip setup) command to go6537 * out in parrallel.6538 */6539int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)6540{6541	int rval = QLA_FUNCTION_FAILED;6542	srb_t *sp;6543	struct srb_iocb *c;6544 6545	if (!vha->hw->flags.fw_started)6546		goto done;6547 6548	/* ref: INIT */6549	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);6550	if (!sp)6551		goto done;6552 6553	c = &sp->u.iocb_cmd;6554	init_completion(&c->u.mbx.comp);6555 6556	sp->type = SRB_MB_IOCB;6557	sp->name = mb_to_str(mcp->mb[0]);6558	qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,6559			      qla2x00_async_mb_sp_done);6560 6561	memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);6562 6563	rval = qla2x00_start_sp(sp);6564	if (rval != QLA_SUCCESS) {6565		ql_dbg(ql_dbg_mbx, vha, 0x1018,6566		    "%s: %s Failed submission. %x.\n",6567		    __func__, sp->name, rval);6568		goto done_free_sp;6569	}6570 6571	ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n",6572	    sp->name, sp->handle);6573 6574	wait_for_completion(&c->u.mbx.comp);6575	memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);6576 6577	rval = c->u.mbx.rc;6578	switch (rval) {6579	case QLA_FUNCTION_TIMEOUT:6580		ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n",6581		    __func__, sp->name, rval);6582		break;6583	case  QLA_SUCCESS:6584		ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",6585		    __func__, sp->name);6586		break;6587	default:6588		ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",6589		    __func__, sp->name, rval);6590		break;6591	}6592 6593done_free_sp:6594	/* ref: INIT */6595	kref_put(&sp->cmd_kref, qla2x00_sp_release);6596done:6597	return rval;6598}6599 6600/*6601 * qla24xx_gpdb_wait6602 * NOTE: Do not call this routine from DPC thread6603 */6604int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)6605{6606	int rval = QLA_FUNCTION_FAILED;6607	dma_addr_t pd_dma;6608	struct port_database_24xx *pd;6609	struct qla_hw_data *ha = vha->hw;6610	mbx_cmd_t mc;6611 6612	if (!vha->hw->flags.fw_started)6613		goto done;6614 6615	pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);6616	if (pd  == NULL) {6617		ql_log(ql_log_warn, vha, 0xd047,6618		    "Failed to allocate port database structure.\n");6619		goto done_free_sp;6620	}6621 6622	memset(&mc, 0, sizeof(mc));6623	mc.mb[0] = MBC_GET_PORT_DATABASE;6624	mc.mb[1] = fcport->loop_id;6625	mc.mb[2] = MSW(pd_dma);6626	mc.mb[3] = LSW(pd_dma);6627	mc.mb[6] = MSW(MSD(pd_dma));6628	mc.mb[7] = LSW(MSD(pd_dma));6629	mc.mb[9] = vha->vp_idx;6630	mc.mb[10] = opt;6631 6632	rval = qla24xx_send_mb_cmd(vha, &mc);6633	if (rval != QLA_SUCCESS) {6634		ql_dbg(ql_dbg_mbx, vha, 0x1193,6635		    "%s: %8phC fail\n", __func__, fcport->port_name);6636		goto done_free_sp;6637	}6638 6639	rval = __qla24xx_parse_gpdb(vha, fcport, pd);6640 6641	ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",6642	    __func__, fcport->port_name);6643 6644done_free_sp:6645	if (pd)6646		dma_pool_free(ha->s_dma_pool, pd, pd_dma);6647done:6648	return rval;6649}6650 6651int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,6652    struct port_database_24xx *pd)6653{6654	int rval = QLA_SUCCESS;6655	uint64_t zero = 0;6656	u8 current_login_state, last_login_state;6657 6658	if (NVME_TARGET(vha->hw, fcport)) {6659		current_login_state = pd->current_login_state >> 4;6660		last_login_state = pd->last_login_state >> 4;6661	} else {6662		current_login_state = pd->current_login_state & 0xf;6663		last_login_state = pd->last_login_state & 0xf;6664	}6665 6666	/* Check for logged in state. */6667	if (current_login_state != PDS_PRLI_COMPLETE) {6668		ql_dbg(ql_dbg_mbx, vha, 0x119a,6669		    "Unable to verify login-state (%x/%x) for loop_id %x.\n",6670		    current_login_state, last_login_state, fcport->loop_id);6671		rval = QLA_FUNCTION_FAILED;6672		goto gpd_error_out;6673	}6674 6675	if (fcport->loop_id == FC_NO_LOOP_ID ||6676	    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&6677	     memcmp(fcport->port_name, pd->port_name, 8))) {6678		/* We lost the device mid way. */6679		rval = QLA_NOT_LOGGED_IN;6680		goto gpd_error_out;6681	}6682 6683	/* Names are little-endian. */6684	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);6685	memcpy(fcport->port_name, pd->port_name, WWN_SIZE);6686 6687	/* Get port_id of device. */6688	fcport->d_id.b.domain = pd->port_id[0];6689	fcport->d_id.b.area = pd->port_id[1];6690	fcport->d_id.b.al_pa = pd->port_id[2];6691	fcport->d_id.b.rsvd_1 = 0;6692 6693	ql_dbg(ql_dbg_disc, vha, 0x2062,6694	     "%8phC SVC Param w3 %02x%02x",6695	     fcport->port_name,6696	     pd->prli_svc_param_word_3[1],6697	     pd->prli_svc_param_word_3[0]);6698 6699	if (NVME_TARGET(vha->hw, fcport)) {6700		fcport->port_type = FCT_NVME;6701		if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)6702			fcport->port_type |= FCT_NVME_INITIATOR;6703		if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)6704			fcport->port_type |= FCT_NVME_TARGET;6705		if ((pd->prli_svc_param_word_3[0] & BIT_3) == 0)6706			fcport->port_type |= FCT_NVME_DISCOVERY;6707	} else {6708		/* If not target must be initiator or unknown type. */6709		if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)6710			fcport->port_type = FCT_INITIATOR;6711		else6712			fcport->port_type = FCT_TARGET;6713	}6714	/* Passback COS information. */6715	fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?6716		FC_COS_CLASS2 : FC_COS_CLASS3;6717 6718	if (pd->prli_svc_param_word_3[0] & BIT_7) {6719		fcport->flags |= FCF_CONF_COMP_SUPPORTED;6720		fcport->conf_compl_supported = 1;6721	}6722 6723gpd_error_out:6724	return rval;6725}6726 6727/*6728 * qla24xx_gidlist__wait6729 * NOTE: don't call this routine from DPC thread.6730 */6731int qla24xx_gidlist_wait(struct scsi_qla_host *vha,6732	void *id_list, dma_addr_t id_list_dma, uint16_t *entries)6733{6734	int rval = QLA_FUNCTION_FAILED;6735	mbx_cmd_t mc;6736 6737	if (!vha->hw->flags.fw_started)6738		goto done;6739 6740	memset(&mc, 0, sizeof(mc));6741	mc.mb[0] = MBC_GET_ID_LIST;6742	mc.mb[2] = MSW(id_list_dma);6743	mc.mb[3] = LSW(id_list_dma);6744	mc.mb[6] = MSW(MSD(id_list_dma));6745	mc.mb[7] = LSW(MSD(id_list_dma));6746	mc.mb[8] = 0;6747	mc.mb[9] = vha->vp_idx;6748 6749	rval = qla24xx_send_mb_cmd(vha, &mc);6750	if (rval != QLA_SUCCESS) {6751		ql_dbg(ql_dbg_mbx, vha, 0x119b,6752		    "%s:  fail\n", __func__);6753	} else {6754		*entries = mc.mb[1];6755		ql_dbg(ql_dbg_mbx, vha, 0x119c,6756		    "%s:  done\n", __func__);6757	}6758done:6759	return rval;6760}6761 6762int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value)6763{6764	int rval;6765	mbx_cmd_t	mc;6766	mbx_cmd_t	*mcp = &mc;6767 6768	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200,6769	    "Entered %s\n", __func__);6770 6771	memset(mcp->mb, 0 , sizeof(mcp->mb));6772	mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;6773	mcp->mb[1] = 1;6774	mcp->mb[2] = value;6775	mcp->out_mb = MBX_2 | MBX_1 | MBX_0;6776	mcp->in_mb = MBX_2 | MBX_0;6777	mcp->tov = MBX_TOV_SECONDS;6778	mcp->flags = 0;6779 6780	rval = qla2x00_mailbox_command(vha, mcp);6781 6782	ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n",6783	    (rval != QLA_SUCCESS) ? "Failed"  : "Done", rval);6784 6785	return rval;6786}6787 6788int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value)6789{6790	int rval;6791	mbx_cmd_t	mc;6792	mbx_cmd_t	*mcp = &mc;6793 6794	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203,6795	    "Entered %s\n", __func__);6796 6797	memset(mcp->mb, 0, sizeof(mcp->mb));6798	mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;6799	mcp->mb[1] = 0;6800	mcp->out_mb = MBX_1 | MBX_0;6801	mcp->in_mb = MBX_2 | MBX_0;6802	mcp->tov = MBX_TOV_SECONDS;6803	mcp->flags = 0;6804 6805	rval = qla2x00_mailbox_command(vha, mcp);6806	if (rval == QLA_SUCCESS)6807		*value = mc.mb[2];6808 6809	ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n",6810	    (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);6811 6812	return rval;6813}6814 6815int6816qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count)6817{6818	struct qla_hw_data *ha = vha->hw;6819	uint16_t iter, addr, offset;6820	dma_addr_t phys_addr;6821	int rval, c;6822	u8 *sfp_data;6823 6824	memset(ha->sfp_data, 0, SFP_DEV_SIZE);6825	addr = 0xa0;6826	phys_addr = ha->sfp_data_dma;6827	sfp_data = ha->sfp_data;6828	offset = c = 0;6829 6830	for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) {6831		if (iter == 4) {6832			/* Skip to next device address. */6833			addr = 0xa2;6834			offset = 0;6835		}6836 6837		rval = qla2x00_read_sfp(vha, phys_addr, sfp_data,6838		    addr, offset, SFP_BLOCK_SIZE, BIT_1);6839		if (rval != QLA_SUCCESS) {6840			ql_log(ql_log_warn, vha, 0x706d,6841			    "Unable to read SFP data (%x/%x/%x).\n", rval,6842			    addr, offset);6843 6844			return rval;6845		}6846 6847		if (buf && (c < count)) {6848			u16 sz;6849 6850			if ((count - c) >= SFP_BLOCK_SIZE)6851				sz = SFP_BLOCK_SIZE;6852			else6853				sz = count - c;6854 6855			memcpy(buf, sfp_data, sz);6856			buf += SFP_BLOCK_SIZE;6857			c += sz;6858		}6859		phys_addr += SFP_BLOCK_SIZE;6860		sfp_data  += SFP_BLOCK_SIZE;6861		offset += SFP_BLOCK_SIZE;6862	}6863 6864	return rval;6865}6866 6867int qla24xx_res_count_wait(struct scsi_qla_host *vha,6868    uint16_t *out_mb, int out_mb_sz)6869{6870	int rval = QLA_FUNCTION_FAILED;6871	mbx_cmd_t mc;6872 6873	if (!vha->hw->flags.fw_started)6874		goto done;6875 6876	memset(&mc, 0, sizeof(mc));6877	mc.mb[0] = MBC_GET_RESOURCE_COUNTS;6878 6879	rval = qla24xx_send_mb_cmd(vha, &mc);6880	if (rval != QLA_SUCCESS) {6881		ql_dbg(ql_dbg_mbx, vha, 0xffff,6882			"%s:  fail\n", __func__);6883	} else {6884		if (out_mb_sz <= SIZEOF_IOCB_MB_REG)6885			memcpy(out_mb, mc.mb, out_mb_sz);6886		else6887			memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);6888 6889		ql_dbg(ql_dbg_mbx, vha, 0xffff,6890			"%s:  done\n", __func__);6891	}6892done:6893	return rval;6894}6895 6896int qla28xx_secure_flash_update(scsi_qla_host_t *vha, uint16_t opts,6897    uint16_t region, uint32_t len, dma_addr_t sfub_dma_addr,6898    uint32_t sfub_len)6899{6900	int		rval;6901	mbx_cmd_t mc;6902	mbx_cmd_t *mcp = &mc;6903 6904	mcp->mb[0] = MBC_SECURE_FLASH_UPDATE;6905	mcp->mb[1] = opts;6906	mcp->mb[2] = region;6907	mcp->mb[3] = MSW(len);6908	mcp->mb[4] = LSW(len);6909	mcp->mb[5] = MSW(sfub_dma_addr);6910	mcp->mb[6] = LSW(sfub_dma_addr);6911	mcp->mb[7] = MSW(MSD(sfub_dma_addr));6912	mcp->mb[8] = LSW(MSD(sfub_dma_addr));6913	mcp->mb[9] = sfub_len;6914	mcp->out_mb =6915	    MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;6916	mcp->in_mb = MBX_2|MBX_1|MBX_0;6917	mcp->tov = MBX_TOV_SECONDS;6918	mcp->flags = 0;6919	rval = qla2x00_mailbox_command(vha, mcp);6920 6921	if (rval != QLA_SUCCESS) {6922		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s(%ld): failed rval 0x%x, %x %x %x",6923			__func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1],6924			mcp->mb[2]);6925	}6926 6927	return rval;6928}6929 6930int qla2xxx_write_remote_register(scsi_qla_host_t *vha, uint32_t addr,6931    uint32_t data)6932{6933	int rval;6934	mbx_cmd_t mc;6935	mbx_cmd_t *mcp = &mc;6936 6937	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,6938	    "Entered %s.\n", __func__);6939 6940	mcp->mb[0] = MBC_WRITE_REMOTE_REG;6941	mcp->mb[1] = LSW(addr);6942	mcp->mb[2] = MSW(addr);6943	mcp->mb[3] = LSW(data);6944	mcp->mb[4] = MSW(data);6945	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;6946	mcp->in_mb = MBX_1|MBX_0;6947	mcp->tov = MBX_TOV_SECONDS;6948	mcp->flags = 0;6949	rval = qla2x00_mailbox_command(vha, mcp);6950 6951	if (rval != QLA_SUCCESS) {6952		ql_dbg(ql_dbg_mbx, vha, 0x10e9,6953		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6954	} else {6955		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,6956		    "Done %s.\n", __func__);6957	}6958 6959	return rval;6960}6961 6962int qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr,6963    uint32_t *data)6964{6965	int rval;6966	mbx_cmd_t mc;6967	mbx_cmd_t *mcp = &mc;6968 6969	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,6970	    "Entered %s.\n", __func__);6971 6972	mcp->mb[0] = MBC_READ_REMOTE_REG;6973	mcp->mb[1] = LSW(addr);6974	mcp->mb[2] = MSW(addr);6975	mcp->out_mb = MBX_2|MBX_1|MBX_0;6976	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;6977	mcp->tov = MBX_TOV_SECONDS;6978	mcp->flags = 0;6979	rval = qla2x00_mailbox_command(vha, mcp);6980 6981	*data = (uint32_t)((((uint32_t)mcp->mb[4]) << 16) | mcp->mb[3]);6982 6983	if (rval != QLA_SUCCESS) {6984		ql_dbg(ql_dbg_mbx, vha, 0x10e9,6985		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);6986	} else {6987		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,6988		    "Done %s.\n", __func__);6989	}6990 6991	return rval;6992}6993 6994int6995ql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led)6996{6997	struct qla_hw_data *ha = vha->hw;6998	mbx_cmd_t mc;6999	mbx_cmd_t *mcp = &mc;7000	int rval;7001 7002	if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))7003		return QLA_FUNCTION_FAILED;7004 7005	ql_dbg(ql_dbg_mbx, vha, 0x7070, "Entered %s (options=%x).\n",7006	    __func__, options);7007 7008	mcp->mb[0] = MBC_SET_GET_FC_LED_CONFIG;7009	mcp->mb[1] = options;7010	mcp->out_mb = MBX_1|MBX_0;7011	mcp->in_mb = MBX_1|MBX_0;7012	if (options & BIT_0) {7013		if (options & BIT_1) {7014			mcp->mb[2] = led[2];7015			mcp->out_mb |= MBX_2;7016		}7017		if (options & BIT_2) {7018			mcp->mb[3] = led[0];7019			mcp->out_mb |= MBX_3;7020		}7021		if (options & BIT_3) {7022			mcp->mb[4] = led[1];7023			mcp->out_mb |= MBX_4;7024		}7025	} else {7026		mcp->in_mb |= MBX_4|MBX_3|MBX_2;7027	}7028	mcp->tov = MBX_TOV_SECONDS;7029	mcp->flags = 0;7030	rval = qla2x00_mailbox_command(vha, mcp);7031	if (rval) {7032		ql_dbg(ql_dbg_mbx, vha, 0x7071, "Failed %s %x (mb=%x,%x)\n",7033		    __func__, rval, mcp->mb[0], mcp->mb[1]);7034		return rval;7035	}7036 7037	if (options & BIT_0) {7038		ha->beacon_blink_led = 0;7039		ql_dbg(ql_dbg_mbx, vha, 0x7072, "Done %s\n", __func__);7040	} else {7041		led[2] = mcp->mb[2];7042		led[0] = mcp->mb[3];7043		led[1] = mcp->mb[4];7044		ql_dbg(ql_dbg_mbx, vha, 0x7073, "Done %s (led=%x,%x,%x)\n",7045		    __func__, led[0], led[1], led[2]);7046	}7047 7048	return rval;7049}7050 7051/**7052 * qla_no_op_mb(): This MB is used to check if FW is still alive and7053 * able to generate an interrupt. Otherwise, a timeout will trigger7054 * FW dump + reset7055 * @vha: host adapter pointer7056 * Return: None7057 */7058void qla_no_op_mb(struct scsi_qla_host *vha)7059{7060	mbx_cmd_t mc;7061	mbx_cmd_t *mcp = &mc;7062	int rval;7063 7064	memset(&mc, 0, sizeof(mc));7065	mcp->mb[0] = 0; // noop cmd= 07066	mcp->out_mb = MBX_0;7067	mcp->in_mb = MBX_0;7068	mcp->tov = 5;7069	mcp->flags = 0;7070	rval = qla2x00_mailbox_command(vha, mcp);7071 7072	if (rval) {7073		ql_dbg(ql_dbg_async, vha, 0x7071,7074			"Failed %s %x\n", __func__, rval);7075	}7076}7077 7078int qla_mailbox_passthru(scsi_qla_host_t *vha,7079			 uint16_t *mbx_in, uint16_t *mbx_out)7080{7081	mbx_cmd_t mc;7082	mbx_cmd_t *mcp = &mc;7083	int rval = -EINVAL;7084 7085	memset(&mc, 0, sizeof(mc));7086	/* Receiving all 32 register's contents */7087	memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t)));7088 7089	mcp->out_mb = 0xFFFFFFFF;7090	mcp->in_mb = 0xFFFFFFFF;7091 7092	mcp->tov = MBX_TOV_SECONDS;7093	mcp->flags = 0;7094	mcp->bufp = NULL;7095 7096	rval = qla2x00_mailbox_command(vha, mcp);7097 7098	if (rval != QLA_SUCCESS) {7099		ql_dbg(ql_dbg_mbx, vha, 0xf0a2,7100			"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);7101	} else {7102		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n",7103		       __func__);7104		/* passing all 32 register's contents */7105		memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t));7106	}7107 7108	return rval;7109}7110