xref: /openbmc/linux/drivers/scsi/qla2xxx/qla_mbx.c (revision d236d361)
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2014 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8 #include "qla_target.h"
9 
10 #include <linux/delay.h>
11 #include <linux/gfp.h>
12 
13 static struct mb_cmd_name {
14 	uint16_t cmd;
15 	const char *str;
16 } mb_str[] = {
17 	{MBC_GET_PORT_DATABASE,		"GPDB"},
18 	{MBC_GET_ID_LIST,		"GIDList"},
19 	{MBC_GET_LINK_PRIV_STATS,	"Stats"},
20 };
21 
22 static const char *mb_to_str(uint16_t cmd)
23 {
24 	int i;
25 	struct mb_cmd_name *e;
26 
27 	for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
28 		e = mb_str + i;
29 		if (cmd == e->cmd)
30 			return e->str;
31 	}
32 	return "unknown";
33 }
34 
35 static struct rom_cmd {
36 	uint16_t cmd;
37 } rom_cmds[] = {
38 	{ MBC_LOAD_RAM },
39 	{ MBC_EXECUTE_FIRMWARE },
40 	{ MBC_READ_RAM_WORD },
41 	{ MBC_MAILBOX_REGISTER_TEST },
42 	{ MBC_VERIFY_CHECKSUM },
43 	{ MBC_GET_FIRMWARE_VERSION },
44 	{ MBC_LOAD_RISC_RAM },
45 	{ MBC_DUMP_RISC_RAM },
46 	{ MBC_LOAD_RISC_RAM_EXTENDED },
47 	{ MBC_DUMP_RISC_RAM_EXTENDED },
48 	{ MBC_WRITE_RAM_WORD_EXTENDED },
49 	{ MBC_READ_RAM_EXTENDED },
50 	{ MBC_GET_RESOURCE_COUNTS },
51 	{ MBC_SET_FIRMWARE_OPTION },
52 	{ MBC_MID_INITIALIZE_FIRMWARE },
53 	{ MBC_GET_FIRMWARE_STATE },
54 	{ MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
55 	{ MBC_GET_RETRY_COUNT },
56 	{ MBC_TRACE_CONTROL },
57 };
58 
59 static int is_rom_cmd(uint16_t cmd)
60 {
61 	int i;
62 	struct  rom_cmd *wc;
63 
64 	for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
65 		wc = rom_cmds + i;
66 		if (wc->cmd == cmd)
67 			return 1;
68 	}
69 
70 	return 0;
71 }
72 
73 /*
74  * qla2x00_mailbox_command
75  *	Issue mailbox command and waits for completion.
76  *
77  * Input:
78  *	ha = adapter block pointer.
79  *	mcp = driver internal mbx struct pointer.
80  *
81  * Output:
82  *	mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
83  *
84  * Returns:
85  *	0 : QLA_SUCCESS = cmd performed success
86  *	1 : QLA_FUNCTION_FAILED   (error encountered)
87  *	6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
88  *
89  * Context:
90  *	Kernel context.
91  */
92 static int
93 qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
94 {
95 	int		rval, i;
96 	unsigned long    flags = 0;
97 	device_reg_t *reg;
98 	uint8_t		abort_active;
99 	uint8_t		io_lock_on;
100 	uint16_t	command = 0;
101 	uint16_t	*iptr;
102 	uint16_t __iomem *optr;
103 	uint32_t	cnt;
104 	uint32_t	mboxes;
105 	uint16_t __iomem *mbx_reg;
106 	unsigned long	wait_time;
107 	struct qla_hw_data *ha = vha->hw;
108 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
109 
110 
111 	ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
112 
113 	if (ha->pdev->error_state > pci_channel_io_frozen) {
114 		ql_log(ql_log_warn, vha, 0x1001,
115 		    "error_state is greater than pci_channel_io_frozen, "
116 		    "exiting.\n");
117 		return QLA_FUNCTION_TIMEOUT;
118 	}
119 
120 	if (vha->device_flags & DFLG_DEV_FAILED) {
121 		ql_log(ql_log_warn, vha, 0x1002,
122 		    "Device in failed state, exiting.\n");
123 		return QLA_FUNCTION_TIMEOUT;
124 	}
125 
126 	/* if PCI error, then avoid mbx processing.*/
127 	if (test_bit(PCI_ERR, &base_vha->dpc_flags)) {
128 		ql_log(ql_log_warn, vha, 0x1191,
129 		    "PCI error, exiting.\n");
130 		return QLA_FUNCTION_TIMEOUT;
131 	}
132 
133 	reg = ha->iobase;
134 	io_lock_on = base_vha->flags.init_done;
135 
136 	rval = QLA_SUCCESS;
137 	abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
138 
139 
140 	if (ha->flags.pci_channel_io_perm_failure) {
141 		ql_log(ql_log_warn, vha, 0x1003,
142 		    "Perm failure on EEH timeout MBX, exiting.\n");
143 		return QLA_FUNCTION_TIMEOUT;
144 	}
145 
146 	if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
147 		/* Setting Link-Down error */
148 		mcp->mb[0] = MBS_LINK_DOWN_ERROR;
149 		ql_log(ql_log_warn, vha, 0x1004,
150 		    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
151 		return QLA_FUNCTION_TIMEOUT;
152 	}
153 
154 	/* check if ISP abort is active and return cmd with timeout */
155 	if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
156 	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
157 	    test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
158 	    !is_rom_cmd(mcp->mb[0])) {
159 		ql_log(ql_log_info, vha, 0x1005,
160 		    "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
161 		    mcp->mb[0]);
162 		return QLA_FUNCTION_TIMEOUT;
163 	}
164 
165 	/*
166 	 * Wait for active mailbox commands to finish by waiting at most tov
167 	 * seconds. This is to serialize actual issuing of mailbox cmds during
168 	 * non ISP abort time.
169 	 */
170 	if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
171 		/* Timeout occurred. Return error. */
172 		ql_log(ql_log_warn, vha, 0x1005,
173 		    "Cmd access timeout, cmd=0x%x, Exiting.\n",
174 		    mcp->mb[0]);
175 		return QLA_FUNCTION_TIMEOUT;
176 	}
177 
178 	ha->flags.mbox_busy = 1;
179 	/* Save mailbox command for debug */
180 	ha->mcp = mcp;
181 
182 	ql_dbg(ql_dbg_mbx, vha, 0x1006,
183 	    "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
184 
185 	spin_lock_irqsave(&ha->hardware_lock, flags);
186 
187 	/* Load mailbox registers. */
188 	if (IS_P3P_TYPE(ha))
189 		optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
190 	else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
191 		optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
192 	else
193 		optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
194 
195 	iptr = mcp->mb;
196 	command = mcp->mb[0];
197 	mboxes = mcp->out_mb;
198 
199 	ql_dbg(ql_dbg_mbx, vha, 0x1111,
200 	    "Mailbox registers (OUT):\n");
201 	for (cnt = 0; cnt < ha->mbx_count; cnt++) {
202 		if (IS_QLA2200(ha) && cnt == 8)
203 			optr =
204 			    (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
205 		if (mboxes & BIT_0) {
206 			ql_dbg(ql_dbg_mbx, vha, 0x1112,
207 			    "mbox[%d]<-0x%04x\n", cnt, *iptr);
208 			WRT_REG_WORD(optr, *iptr);
209 		}
210 
211 		mboxes >>= 1;
212 		optr++;
213 		iptr++;
214 	}
215 
216 	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
217 	    "I/O Address = %p.\n", optr);
218 
219 	/* Issue set host interrupt command to send cmd out. */
220 	ha->flags.mbox_int = 0;
221 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
222 
223 	/* Unlock mbx registers and wait for interrupt */
224 	ql_dbg(ql_dbg_mbx, vha, 0x100f,
225 	    "Going to unlock irq & waiting for interrupts. "
226 	    "jiffies=%lx.\n", jiffies);
227 
228 	/* Wait for mbx cmd completion until timeout */
229 
230 	if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
231 		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
232 
233 		if (IS_P3P_TYPE(ha)) {
234 			if (RD_REG_DWORD(&reg->isp82.hint) &
235 				HINT_MBX_INT_PENDING) {
236 				spin_unlock_irqrestore(&ha->hardware_lock,
237 					flags);
238 				ha->flags.mbox_busy = 0;
239 				ql_dbg(ql_dbg_mbx, vha, 0x1010,
240 				    "Pending mailbox timeout, exiting.\n");
241 				rval = QLA_FUNCTION_TIMEOUT;
242 				goto premature_exit;
243 			}
244 			WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
245 		} else if (IS_FWI2_CAPABLE(ha))
246 			WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
247 		else
248 			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
249 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
250 
251 		wait_time = jiffies;
252 		if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
253 		    mcp->tov * HZ)) {
254 			ql_dbg(ql_dbg_mbx, vha, 0x117a,
255 			    "cmd=%x Timeout.\n", command);
256 			spin_lock_irqsave(&ha->hardware_lock, flags);
257 			clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
258 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
259 		}
260 		if (time_after(jiffies, wait_time + 5 * HZ))
261 			ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
262 			    command, jiffies_to_msecs(jiffies - wait_time));
263 	} else {
264 		ql_dbg(ql_dbg_mbx, vha, 0x1011,
265 		    "Cmd=%x Polling Mode.\n", command);
266 
267 		if (IS_P3P_TYPE(ha)) {
268 			if (RD_REG_DWORD(&reg->isp82.hint) &
269 				HINT_MBX_INT_PENDING) {
270 				spin_unlock_irqrestore(&ha->hardware_lock,
271 					flags);
272 				ha->flags.mbox_busy = 0;
273 				ql_dbg(ql_dbg_mbx, vha, 0x1012,
274 				    "Pending mailbox timeout, exiting.\n");
275 				rval = QLA_FUNCTION_TIMEOUT;
276 				goto premature_exit;
277 			}
278 			WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
279 		} else if (IS_FWI2_CAPABLE(ha))
280 			WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
281 		else
282 			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
283 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
284 
285 		wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
286 		while (!ha->flags.mbox_int) {
287 			if (time_after(jiffies, wait_time))
288 				break;
289 
290 			/* Check for pending interrupts. */
291 			qla2x00_poll(ha->rsp_q_map[0]);
292 
293 			if (!ha->flags.mbox_int &&
294 			    !(IS_QLA2200(ha) &&
295 			    command == MBC_LOAD_RISC_RAM_EXTENDED))
296 				msleep(10);
297 		} /* while */
298 		ql_dbg(ql_dbg_mbx, vha, 0x1013,
299 		    "Waited %d sec.\n",
300 		    (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
301 	}
302 
303 	/* Check whether we timed out */
304 	if (ha->flags.mbox_int) {
305 		uint16_t *iptr2;
306 
307 		ql_dbg(ql_dbg_mbx, vha, 0x1014,
308 		    "Cmd=%x completed.\n", command);
309 
310 		/* Got interrupt. Clear the flag. */
311 		ha->flags.mbox_int = 0;
312 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
313 
314 		if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
315 			ha->flags.mbox_busy = 0;
316 			/* Setting Link-Down error */
317 			mcp->mb[0] = MBS_LINK_DOWN_ERROR;
318 			ha->mcp = NULL;
319 			rval = QLA_FUNCTION_FAILED;
320 			ql_log(ql_log_warn, vha, 0x1015,
321 			    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
322 			goto premature_exit;
323 		}
324 
325 		if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
326 			rval = QLA_FUNCTION_FAILED;
327 
328 		/* Load return mailbox registers. */
329 		iptr2 = mcp->mb;
330 		iptr = (uint16_t *)&ha->mailbox_out[0];
331 		mboxes = mcp->in_mb;
332 
333 		ql_dbg(ql_dbg_mbx, vha, 0x1113,
334 		    "Mailbox registers (IN):\n");
335 		for (cnt = 0; cnt < ha->mbx_count; cnt++) {
336 			if (mboxes & BIT_0) {
337 				*iptr2 = *iptr;
338 				ql_dbg(ql_dbg_mbx, vha, 0x1114,
339 				    "mbox[%d]->0x%04x\n", cnt, *iptr2);
340 			}
341 
342 			mboxes >>= 1;
343 			iptr2++;
344 			iptr++;
345 		}
346 	} else {
347 
348 		uint16_t mb[8];
349 		uint32_t ictrl, host_status, hccr;
350 		uint16_t        w;
351 
352 		if (IS_FWI2_CAPABLE(ha)) {
353 			mb[0] = RD_REG_WORD(&reg->isp24.mailbox0);
354 			mb[1] = RD_REG_WORD(&reg->isp24.mailbox1);
355 			mb[2] = RD_REG_WORD(&reg->isp24.mailbox2);
356 			mb[3] = RD_REG_WORD(&reg->isp24.mailbox3);
357 			mb[7] = RD_REG_WORD(&reg->isp24.mailbox7);
358 			ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
359 			host_status = RD_REG_DWORD(&reg->isp24.host_status);
360 			hccr = RD_REG_DWORD(&reg->isp24.hccr);
361 
362 			ql_log(ql_log_warn, vha, 0x1119,
363 			    "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
364 			    "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",
365 			    command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],
366 			    mb[7], host_status, hccr);
367 
368 		} else {
369 			mb[0] = RD_MAILBOX_REG(ha, &reg->isp, 0);
370 			ictrl = RD_REG_WORD(&reg->isp.ictrl);
371 			ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
372 			    "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
373 			    "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);
374 		}
375 		ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
376 
377 		/* Capture FW dump only, if PCI device active */
378 		if (!pci_channel_offline(vha->hw->pdev)) {
379 			pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
380 			if (w == 0xffff || ictrl == 0xffffffff) {
381 				/* This is special case if there is unload
382 				 * of driver happening and if PCI device go
383 				 * into bad state due to PCI error condition
384 				 * then only PCI ERR flag would be set.
385 				 * we will do premature exit for above case.
386 				 */
387 				if (test_bit(UNLOADING, &base_vha->dpc_flags))
388 					set_bit(PCI_ERR, &base_vha->dpc_flags);
389 				ha->flags.mbox_busy = 0;
390 				rval = QLA_FUNCTION_TIMEOUT;
391 				goto premature_exit;
392 			}
393 
394 			/* Attempt to capture firmware dump for further
395 			 * anallysis of the current formware state. we do not
396 			 * need to do this if we are intentionally generating
397 			 * a dump
398 			 */
399 			if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
400 				ha->isp_ops->fw_dump(vha, 0);
401 			rval = QLA_FUNCTION_TIMEOUT;
402 		 }
403 	}
404 
405 	ha->flags.mbox_busy = 0;
406 
407 	/* Clean up */
408 	ha->mcp = NULL;
409 
410 	if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
411 		ql_dbg(ql_dbg_mbx, vha, 0x101a,
412 		    "Checking for additional resp interrupt.\n");
413 
414 		/* polling mode for non isp_abort commands. */
415 		qla2x00_poll(ha->rsp_q_map[0]);
416 	}
417 
418 	if (rval == QLA_FUNCTION_TIMEOUT &&
419 	    mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
420 		if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
421 		    ha->flags.eeh_busy) {
422 			/* not in dpc. schedule it for dpc to take over. */
423 			ql_dbg(ql_dbg_mbx, vha, 0x101b,
424 			    "Timeout, schedule isp_abort_needed.\n");
425 
426 			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
427 			    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
428 			    !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
429 				if (IS_QLA82XX(ha)) {
430 					ql_dbg(ql_dbg_mbx, vha, 0x112a,
431 					    "disabling pause transmit on port "
432 					    "0 & 1.\n");
433 					qla82xx_wr_32(ha,
434 					    QLA82XX_CRB_NIU + 0x98,
435 					    CRB_NIU_XG_PAUSE_CTL_P0|
436 					    CRB_NIU_XG_PAUSE_CTL_P1);
437 				}
438 				ql_log(ql_log_info, base_vha, 0x101c,
439 				    "Mailbox cmd timeout occurred, cmd=0x%x, "
440 				    "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
441 				    "abort.\n", command, mcp->mb[0],
442 				    ha->flags.eeh_busy);
443 				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
444 				qla2xxx_wake_dpc(vha);
445 			}
446 		} else if (!abort_active) {
447 			/* call abort directly since we are in the DPC thread */
448 			ql_dbg(ql_dbg_mbx, vha, 0x101d,
449 			    "Timeout, calling abort_isp.\n");
450 
451 			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
452 			    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
453 			    !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
454 				if (IS_QLA82XX(ha)) {
455 					ql_dbg(ql_dbg_mbx, vha, 0x112b,
456 					    "disabling pause transmit on port "
457 					    "0 & 1.\n");
458 					qla82xx_wr_32(ha,
459 					    QLA82XX_CRB_NIU + 0x98,
460 					    CRB_NIU_XG_PAUSE_CTL_P0|
461 					    CRB_NIU_XG_PAUSE_CTL_P1);
462 				}
463 				ql_log(ql_log_info, base_vha, 0x101e,
464 				    "Mailbox cmd timeout occurred, cmd=0x%x, "
465 				    "mb[0]=0x%x. Scheduling ISP abort ",
466 				    command, mcp->mb[0]);
467 				set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
468 				clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
469 				/* Allow next mbx cmd to come in. */
470 				complete(&ha->mbx_cmd_comp);
471 				if (ha->isp_ops->abort_isp(vha)) {
472 					/* Failed. retry later. */
473 					set_bit(ISP_ABORT_NEEDED,
474 					    &vha->dpc_flags);
475 				}
476 				clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
477 				ql_dbg(ql_dbg_mbx, vha, 0x101f,
478 				    "Finished abort_isp.\n");
479 				goto mbx_done;
480 			}
481 		}
482 	}
483 
484 premature_exit:
485 	/* Allow next mbx cmd to come in. */
486 	complete(&ha->mbx_cmd_comp);
487 
488 mbx_done:
489 	if (rval) {
490 		ql_dbg(ql_dbg_disc, base_vha, 0x1020,
491 		    "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
492 		    mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
493 
494 		ql_dbg(ql_dbg_mbx, vha, 0x1198,
495 		    "host status: 0x%x, flags:0x%lx, intr ctrl reg:0x%x, intr status:0x%x\n",
496 		    RD_REG_DWORD(&reg->isp24.host_status),
497 		    ha->fw_dump_cap_flags,
498 		    RD_REG_DWORD(&reg->isp24.ictrl),
499 		    RD_REG_DWORD(&reg->isp24.istatus));
500 
501 		mbx_reg = &reg->isp24.mailbox0;
502 		for (i = 0; i < 6; i++)
503 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1199,
504 			    "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
505 	} else {
506 		ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
507 	}
508 
509 	return rval;
510 }
511 
512 int
513 qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
514     uint32_t risc_code_size)
515 {
516 	int rval;
517 	struct qla_hw_data *ha = vha->hw;
518 	mbx_cmd_t mc;
519 	mbx_cmd_t *mcp = &mc;
520 
521 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
522 	    "Entered %s.\n", __func__);
523 
524 	if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
525 		mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
526 		mcp->mb[8] = MSW(risc_addr);
527 		mcp->out_mb = MBX_8|MBX_0;
528 	} else {
529 		mcp->mb[0] = MBC_LOAD_RISC_RAM;
530 		mcp->out_mb = MBX_0;
531 	}
532 	mcp->mb[1] = LSW(risc_addr);
533 	mcp->mb[2] = MSW(req_dma);
534 	mcp->mb[3] = LSW(req_dma);
535 	mcp->mb[6] = MSW(MSD(req_dma));
536 	mcp->mb[7] = LSW(MSD(req_dma));
537 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
538 	if (IS_FWI2_CAPABLE(ha)) {
539 		mcp->mb[4] = MSW(risc_code_size);
540 		mcp->mb[5] = LSW(risc_code_size);
541 		mcp->out_mb |= MBX_5|MBX_4;
542 	} else {
543 		mcp->mb[4] = LSW(risc_code_size);
544 		mcp->out_mb |= MBX_4;
545 	}
546 
547 	mcp->in_mb = MBX_0;
548 	mcp->tov = MBX_TOV_SECONDS;
549 	mcp->flags = 0;
550 	rval = qla2x00_mailbox_command(vha, mcp);
551 
552 	if (rval != QLA_SUCCESS) {
553 		ql_dbg(ql_dbg_mbx, vha, 0x1023,
554 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
555 	} else {
556 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
557 		    "Done %s.\n", __func__);
558 	}
559 
560 	return rval;
561 }
562 
563 #define	EXTENDED_BB_CREDITS	BIT_0
564 /*
565  * qla2x00_execute_fw
566  *     Start adapter firmware.
567  *
568  * Input:
569  *     ha = adapter block pointer.
570  *     TARGET_QUEUE_LOCK must be released.
571  *     ADAPTER_STATE_LOCK must be released.
572  *
573  * Returns:
574  *     qla2x00 local function return status code.
575  *
576  * Context:
577  *     Kernel context.
578  */
579 int
580 qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
581 {
582 	int rval;
583 	struct qla_hw_data *ha = vha->hw;
584 	mbx_cmd_t mc;
585 	mbx_cmd_t *mcp = &mc;
586 
587 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
588 	    "Entered %s.\n", __func__);
589 
590 	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
591 	mcp->out_mb = MBX_0;
592 	mcp->in_mb = MBX_0;
593 	if (IS_FWI2_CAPABLE(ha)) {
594 		mcp->mb[1] = MSW(risc_addr);
595 		mcp->mb[2] = LSW(risc_addr);
596 		mcp->mb[3] = 0;
597 		if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
598 		    IS_QLA27XX(ha)) {
599 			struct nvram_81xx *nv = ha->nvram;
600 			mcp->mb[4] = (nv->enhanced_features &
601 			    EXTENDED_BB_CREDITS);
602 		} else
603 			mcp->mb[4] = 0;
604 
605 		if (ha->flags.exlogins_enabled)
606 			mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
607 
608 		if (ha->flags.exchoffld_enabled)
609 			mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
610 
611 		mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
612 		mcp->in_mb |= MBX_1;
613 	} else {
614 		mcp->mb[1] = LSW(risc_addr);
615 		mcp->out_mb |= MBX_1;
616 		if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
617 			mcp->mb[2] = 0;
618 			mcp->out_mb |= MBX_2;
619 		}
620 	}
621 
622 	mcp->tov = MBX_TOV_SECONDS;
623 	mcp->flags = 0;
624 	rval = qla2x00_mailbox_command(vha, mcp);
625 
626 	if (rval != QLA_SUCCESS) {
627 		ql_dbg(ql_dbg_mbx, vha, 0x1026,
628 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
629 	} else {
630 		if (IS_FWI2_CAPABLE(ha)) {
631 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
632 			    "Done exchanges=%x.\n", mcp->mb[1]);
633 		} else {
634 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
635 			    "Done %s.\n", __func__);
636 		}
637 	}
638 
639 	return rval;
640 }
641 
642 /*
643  * qla_get_exlogin_status
644  *	Get extended login status
645  *	uses the memory offload control/status Mailbox
646  *
647  * Input:
648  *	ha:		adapter state pointer.
649  *	fwopt:		firmware options
650  *
651  * Returns:
652  *	qla2x00 local function status
653  *
654  * Context:
655  *	Kernel context.
656  */
657 #define	FETCH_XLOGINS_STAT	0x8
658 int
659 qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
660 	uint16_t *ex_logins_cnt)
661 {
662 	int rval;
663 	mbx_cmd_t	mc;
664 	mbx_cmd_t	*mcp = &mc;
665 
666 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
667 	    "Entered %s\n", __func__);
668 
669 	memset(mcp->mb, 0 , sizeof(mcp->mb));
670 	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
671 	mcp->mb[1] = FETCH_XLOGINS_STAT;
672 	mcp->out_mb = MBX_1|MBX_0;
673 	mcp->in_mb = MBX_10|MBX_4|MBX_0;
674 	mcp->tov = MBX_TOV_SECONDS;
675 	mcp->flags = 0;
676 
677 	rval = qla2x00_mailbox_command(vha, mcp);
678 	if (rval != QLA_SUCCESS) {
679 		ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
680 	} else {
681 		*buf_sz = mcp->mb[4];
682 		*ex_logins_cnt = mcp->mb[10];
683 
684 		ql_log(ql_log_info, vha, 0x1190,
685 		    "buffer size 0x%x, exchange login count=%d\n",
686 		    mcp->mb[4], mcp->mb[10]);
687 
688 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
689 		    "Done %s.\n", __func__);
690 	}
691 
692 	return rval;
693 }
694 
695 /*
696  * qla_set_exlogin_mem_cfg
697  *	set extended login memory configuration
698  *	Mbx needs to be issues before init_cb is set
699  *
700  * Input:
701  *	ha:		adapter state pointer.
702  *	buffer:		buffer pointer
703  *	phys_addr:	physical address of buffer
704  *	size:		size of buffer
705  *	TARGET_QUEUE_LOCK must be released
706  *	ADAPTER_STATE_LOCK must be release
707  *
708  * Returns:
709  *	qla2x00 local funxtion status code.
710  *
711  * Context:
712  *	Kernel context.
713  */
714 #define CONFIG_XLOGINS_MEM	0x3
715 int
716 qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
717 {
718 	int		rval;
719 	mbx_cmd_t	mc;
720 	mbx_cmd_t	*mcp = &mc;
721 	struct qla_hw_data *ha = vha->hw;
722 
723 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
724 	    "Entered %s.\n", __func__);
725 
726 	memset(mcp->mb, 0 , sizeof(mcp->mb));
727 	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
728 	mcp->mb[1] = CONFIG_XLOGINS_MEM;
729 	mcp->mb[2] = MSW(phys_addr);
730 	mcp->mb[3] = LSW(phys_addr);
731 	mcp->mb[6] = MSW(MSD(phys_addr));
732 	mcp->mb[7] = LSW(MSD(phys_addr));
733 	mcp->mb[8] = MSW(ha->exlogin_size);
734 	mcp->mb[9] = LSW(ha->exlogin_size);
735 	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
736 	mcp->in_mb = MBX_11|MBX_0;
737 	mcp->tov = MBX_TOV_SECONDS;
738 	mcp->flags = 0;
739 	rval = qla2x00_mailbox_command(vha, mcp);
740 	if (rval != QLA_SUCCESS) {
741 		/*EMPTY*/
742 		ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
743 	} else {
744 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
745 		    "Done %s.\n", __func__);
746 	}
747 
748 	return rval;
749 }
750 
751 /*
752  * qla_get_exchoffld_status
753  *	Get exchange offload status
754  *	uses the memory offload control/status Mailbox
755  *
756  * Input:
757  *	ha:		adapter state pointer.
758  *	fwopt:		firmware options
759  *
760  * Returns:
761  *	qla2x00 local function status
762  *
763  * Context:
764  *	Kernel context.
765  */
766 #define	FETCH_XCHOFFLD_STAT	0x2
767 int
768 qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
769 	uint16_t *ex_logins_cnt)
770 {
771 	int rval;
772 	mbx_cmd_t	mc;
773 	mbx_cmd_t	*mcp = &mc;
774 
775 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
776 	    "Entered %s\n", __func__);
777 
778 	memset(mcp->mb, 0 , sizeof(mcp->mb));
779 	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
780 	mcp->mb[1] = FETCH_XCHOFFLD_STAT;
781 	mcp->out_mb = MBX_1|MBX_0;
782 	mcp->in_mb = MBX_10|MBX_4|MBX_0;
783 	mcp->tov = MBX_TOV_SECONDS;
784 	mcp->flags = 0;
785 
786 	rval = qla2x00_mailbox_command(vha, mcp);
787 	if (rval != QLA_SUCCESS) {
788 		ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
789 	} else {
790 		*buf_sz = mcp->mb[4];
791 		*ex_logins_cnt = mcp->mb[10];
792 
793 		ql_log(ql_log_info, vha, 0x118e,
794 		    "buffer size 0x%x, exchange offload count=%d\n",
795 		    mcp->mb[4], mcp->mb[10]);
796 
797 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
798 		    "Done %s.\n", __func__);
799 	}
800 
801 	return rval;
802 }
803 
804 /*
805  * qla_set_exchoffld_mem_cfg
806  *	Set exchange offload memory configuration
807  *	Mbx needs to be issues before init_cb is set
808  *
809  * Input:
810  *	ha:		adapter state pointer.
811  *	buffer:		buffer pointer
812  *	phys_addr:	physical address of buffer
813  *	size:		size of buffer
814  *	TARGET_QUEUE_LOCK must be released
815  *	ADAPTER_STATE_LOCK must be release
816  *
817  * Returns:
818  *	qla2x00 local funxtion status code.
819  *
820  * Context:
821  *	Kernel context.
822  */
823 #define CONFIG_XCHOFFLD_MEM	0x3
824 int
825 qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
826 {
827 	int		rval;
828 	mbx_cmd_t	mc;
829 	mbx_cmd_t	*mcp = &mc;
830 	struct qla_hw_data *ha = vha->hw;
831 
832 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
833 	    "Entered %s.\n", __func__);
834 
835 	memset(mcp->mb, 0 , sizeof(mcp->mb));
836 	mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
837 	mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
838 	mcp->mb[2] = MSW(phys_addr);
839 	mcp->mb[3] = LSW(phys_addr);
840 	mcp->mb[6] = MSW(MSD(phys_addr));
841 	mcp->mb[7] = LSW(MSD(phys_addr));
842 	mcp->mb[8] = MSW(ha->exlogin_size);
843 	mcp->mb[9] = LSW(ha->exlogin_size);
844 	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
845 	mcp->in_mb = MBX_11|MBX_0;
846 	mcp->tov = MBX_TOV_SECONDS;
847 	mcp->flags = 0;
848 	rval = qla2x00_mailbox_command(vha, mcp);
849 	if (rval != QLA_SUCCESS) {
850 		/*EMPTY*/
851 		ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
852 	} else {
853 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
854 		    "Done %s.\n", __func__);
855 	}
856 
857 	return rval;
858 }
859 
860 /*
861  * qla2x00_get_fw_version
862  *	Get firmware version.
863  *
864  * Input:
865  *	ha:		adapter state pointer.
866  *	major:		pointer for major number.
867  *	minor:		pointer for minor number.
868  *	subminor:	pointer for subminor number.
869  *
870  * Returns:
871  *	qla2x00 local function return status code.
872  *
873  * Context:
874  *	Kernel context.
875  */
876 int
877 qla2x00_get_fw_version(scsi_qla_host_t *vha)
878 {
879 	int		rval;
880 	mbx_cmd_t	mc;
881 	mbx_cmd_t	*mcp = &mc;
882 	struct qla_hw_data *ha = vha->hw;
883 
884 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
885 	    "Entered %s.\n", __func__);
886 
887 	mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
888 	mcp->out_mb = MBX_0;
889 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
890 	if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
891 		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
892 	if (IS_FWI2_CAPABLE(ha))
893 		mcp->in_mb |= MBX_17|MBX_16|MBX_15;
894 	if (IS_QLA27XX(ha))
895 		mcp->in_mb |=
896 		    MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
897 		    MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8;
898 
899 	mcp->flags = 0;
900 	mcp->tov = MBX_TOV_SECONDS;
901 	rval = qla2x00_mailbox_command(vha, mcp);
902 	if (rval != QLA_SUCCESS)
903 		goto failed;
904 
905 	/* Return mailbox data. */
906 	ha->fw_major_version = mcp->mb[1];
907 	ha->fw_minor_version = mcp->mb[2];
908 	ha->fw_subminor_version = mcp->mb[3];
909 	ha->fw_attributes = mcp->mb[6];
910 	if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
911 		ha->fw_memory_size = 0x1FFFF;		/* Defaults to 128KB. */
912 	else
913 		ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
914 
915 	if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
916 		ha->mpi_version[0] = mcp->mb[10] & 0xff;
917 		ha->mpi_version[1] = mcp->mb[11] >> 8;
918 		ha->mpi_version[2] = mcp->mb[11] & 0xff;
919 		ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
920 		ha->phy_version[0] = mcp->mb[8] & 0xff;
921 		ha->phy_version[1] = mcp->mb[9] >> 8;
922 		ha->phy_version[2] = mcp->mb[9] & 0xff;
923 	}
924 
925 	if (IS_FWI2_CAPABLE(ha)) {
926 		ha->fw_attributes_h = mcp->mb[15];
927 		ha->fw_attributes_ext[0] = mcp->mb[16];
928 		ha->fw_attributes_ext[1] = mcp->mb[17];
929 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
930 		    "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
931 		    __func__, mcp->mb[15], mcp->mb[6]);
932 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
933 		    "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
934 		    __func__, mcp->mb[17], mcp->mb[16]);
935 
936 		if (ha->fw_attributes_h & 0x4)
937 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
938 			    "%s: Firmware supports Extended Login 0x%x\n",
939 			    __func__, ha->fw_attributes_h);
940 
941 		if (ha->fw_attributes_h & 0x8)
942 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
943 			    "%s: Firmware supports Exchange Offload 0x%x\n",
944 			    __func__, ha->fw_attributes_h);
945 	}
946 
947 	if (IS_QLA27XX(ha)) {
948 		ha->mpi_version[0] = mcp->mb[10] & 0xff;
949 		ha->mpi_version[1] = mcp->mb[11] >> 8;
950 		ha->mpi_version[2] = mcp->mb[11] & 0xff;
951 		ha->pep_version[0] = mcp->mb[13] & 0xff;
952 		ha->pep_version[1] = mcp->mb[14] >> 8;
953 		ha->pep_version[2] = mcp->mb[14] & 0xff;
954 		ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
955 		ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
956 		ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
957 		ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
958 	}
959 
960 failed:
961 	if (rval != QLA_SUCCESS) {
962 		/*EMPTY*/
963 		ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
964 	} else {
965 		/*EMPTY*/
966 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
967 		    "Done %s.\n", __func__);
968 	}
969 	return rval;
970 }
971 
972 /*
973  * qla2x00_get_fw_options
974  *	Set firmware options.
975  *
976  * Input:
977  *	ha = adapter block pointer.
978  *	fwopt = pointer for firmware options.
979  *
980  * Returns:
981  *	qla2x00 local function return status code.
982  *
983  * Context:
984  *	Kernel context.
985  */
986 int
987 qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
988 {
989 	int rval;
990 	mbx_cmd_t mc;
991 	mbx_cmd_t *mcp = &mc;
992 
993 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
994 	    "Entered %s.\n", __func__);
995 
996 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
997 	mcp->out_mb = MBX_0;
998 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
999 	mcp->tov = MBX_TOV_SECONDS;
1000 	mcp->flags = 0;
1001 	rval = qla2x00_mailbox_command(vha, mcp);
1002 
1003 	if (rval != QLA_SUCCESS) {
1004 		/*EMPTY*/
1005 		ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
1006 	} else {
1007 		fwopts[0] = mcp->mb[0];
1008 		fwopts[1] = mcp->mb[1];
1009 		fwopts[2] = mcp->mb[2];
1010 		fwopts[3] = mcp->mb[3];
1011 
1012 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
1013 		    "Done %s.\n", __func__);
1014 	}
1015 
1016 	return rval;
1017 }
1018 
1019 
1020 /*
1021  * qla2x00_set_fw_options
1022  *	Set firmware options.
1023  *
1024  * Input:
1025  *	ha = adapter block pointer.
1026  *	fwopt = pointer for firmware options.
1027  *
1028  * Returns:
1029  *	qla2x00 local function return status code.
1030  *
1031  * Context:
1032  *	Kernel context.
1033  */
1034 int
1035 qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
1036 {
1037 	int rval;
1038 	mbx_cmd_t mc;
1039 	mbx_cmd_t *mcp = &mc;
1040 
1041 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
1042 	    "Entered %s.\n", __func__);
1043 
1044 	mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
1045 	mcp->mb[1] = fwopts[1];
1046 	mcp->mb[2] = fwopts[2];
1047 	mcp->mb[3] = fwopts[3];
1048 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1049 	mcp->in_mb = MBX_0;
1050 	if (IS_FWI2_CAPABLE(vha->hw)) {
1051 		mcp->in_mb |= MBX_1;
1052 	} else {
1053 		mcp->mb[10] = fwopts[10];
1054 		mcp->mb[11] = fwopts[11];
1055 		mcp->mb[12] = 0;	/* Undocumented, but used */
1056 		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
1057 	}
1058 	mcp->tov = MBX_TOV_SECONDS;
1059 	mcp->flags = 0;
1060 	rval = qla2x00_mailbox_command(vha, mcp);
1061 
1062 	fwopts[0] = mcp->mb[0];
1063 
1064 	if (rval != QLA_SUCCESS) {
1065 		/*EMPTY*/
1066 		ql_dbg(ql_dbg_mbx, vha, 0x1030,
1067 		    "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
1068 	} else {
1069 		/*EMPTY*/
1070 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
1071 		    "Done %s.\n", __func__);
1072 	}
1073 
1074 	return rval;
1075 }
1076 
1077 /*
1078  * qla2x00_mbx_reg_test
1079  *	Mailbox register wrap test.
1080  *
1081  * Input:
1082  *	ha = adapter block pointer.
1083  *	TARGET_QUEUE_LOCK must be released.
1084  *	ADAPTER_STATE_LOCK must be released.
1085  *
1086  * Returns:
1087  *	qla2x00 local function return status code.
1088  *
1089  * Context:
1090  *	Kernel context.
1091  */
1092 int
1093 qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
1094 {
1095 	int rval;
1096 	mbx_cmd_t mc;
1097 	mbx_cmd_t *mcp = &mc;
1098 
1099 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
1100 	    "Entered %s.\n", __func__);
1101 
1102 	mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
1103 	mcp->mb[1] = 0xAAAA;
1104 	mcp->mb[2] = 0x5555;
1105 	mcp->mb[3] = 0xAA55;
1106 	mcp->mb[4] = 0x55AA;
1107 	mcp->mb[5] = 0xA5A5;
1108 	mcp->mb[6] = 0x5A5A;
1109 	mcp->mb[7] = 0x2525;
1110 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1111 	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1112 	mcp->tov = MBX_TOV_SECONDS;
1113 	mcp->flags = 0;
1114 	rval = qla2x00_mailbox_command(vha, mcp);
1115 
1116 	if (rval == QLA_SUCCESS) {
1117 		if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
1118 		    mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
1119 			rval = QLA_FUNCTION_FAILED;
1120 		if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
1121 		    mcp->mb[7] != 0x2525)
1122 			rval = QLA_FUNCTION_FAILED;
1123 	}
1124 
1125 	if (rval != QLA_SUCCESS) {
1126 		/*EMPTY*/
1127 		ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
1128 	} else {
1129 		/*EMPTY*/
1130 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
1131 		    "Done %s.\n", __func__);
1132 	}
1133 
1134 	return rval;
1135 }
1136 
1137 /*
1138  * qla2x00_verify_checksum
1139  *	Verify firmware checksum.
1140  *
1141  * Input:
1142  *	ha = adapter block pointer.
1143  *	TARGET_QUEUE_LOCK must be released.
1144  *	ADAPTER_STATE_LOCK must be released.
1145  *
1146  * Returns:
1147  *	qla2x00 local function return status code.
1148  *
1149  * Context:
1150  *	Kernel context.
1151  */
1152 int
1153 qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
1154 {
1155 	int rval;
1156 	mbx_cmd_t mc;
1157 	mbx_cmd_t *mcp = &mc;
1158 
1159 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
1160 	    "Entered %s.\n", __func__);
1161 
1162 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
1163 	mcp->out_mb = MBX_0;
1164 	mcp->in_mb = MBX_0;
1165 	if (IS_FWI2_CAPABLE(vha->hw)) {
1166 		mcp->mb[1] = MSW(risc_addr);
1167 		mcp->mb[2] = LSW(risc_addr);
1168 		mcp->out_mb |= MBX_2|MBX_1;
1169 		mcp->in_mb |= MBX_2|MBX_1;
1170 	} else {
1171 		mcp->mb[1] = LSW(risc_addr);
1172 		mcp->out_mb |= MBX_1;
1173 		mcp->in_mb |= MBX_1;
1174 	}
1175 
1176 	mcp->tov = MBX_TOV_SECONDS;
1177 	mcp->flags = 0;
1178 	rval = qla2x00_mailbox_command(vha, mcp);
1179 
1180 	if (rval != QLA_SUCCESS) {
1181 		ql_dbg(ql_dbg_mbx, vha, 0x1036,
1182 		    "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
1183 		    (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
1184 	} else {
1185 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
1186 		    "Done %s.\n", __func__);
1187 	}
1188 
1189 	return rval;
1190 }
1191 
1192 /*
1193  * qla2x00_issue_iocb
1194  *	Issue IOCB using mailbox command
1195  *
1196  * Input:
1197  *	ha = adapter state pointer.
1198  *	buffer = buffer pointer.
1199  *	phys_addr = physical address of buffer.
1200  *	size = size of buffer.
1201  *	TARGET_QUEUE_LOCK must be released.
1202  *	ADAPTER_STATE_LOCK must be released.
1203  *
1204  * Returns:
1205  *	qla2x00 local function return status code.
1206  *
1207  * Context:
1208  *	Kernel context.
1209  */
1210 int
1211 qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
1212     dma_addr_t phys_addr, size_t size, uint32_t tov)
1213 {
1214 	int		rval;
1215 	mbx_cmd_t	mc;
1216 	mbx_cmd_t	*mcp = &mc;
1217 
1218 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
1219 	    "Entered %s.\n", __func__);
1220 
1221 	mcp->mb[0] = MBC_IOCB_COMMAND_A64;
1222 	mcp->mb[1] = 0;
1223 	mcp->mb[2] = MSW(phys_addr);
1224 	mcp->mb[3] = LSW(phys_addr);
1225 	mcp->mb[6] = MSW(MSD(phys_addr));
1226 	mcp->mb[7] = LSW(MSD(phys_addr));
1227 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1228 	mcp->in_mb = MBX_2|MBX_0;
1229 	mcp->tov = tov;
1230 	mcp->flags = 0;
1231 	rval = qla2x00_mailbox_command(vha, mcp);
1232 
1233 	if (rval != QLA_SUCCESS) {
1234 		/*EMPTY*/
1235 		ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
1236 	} else {
1237 		sts_entry_t *sts_entry = (sts_entry_t *) buffer;
1238 
1239 		/* Mask reserved bits. */
1240 		sts_entry->entry_status &=
1241 		    IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
1242 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1243 		    "Done %s.\n", __func__);
1244 	}
1245 
1246 	return rval;
1247 }
1248 
1249 int
1250 qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
1251     size_t size)
1252 {
1253 	return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
1254 	    MBX_TOV_SECONDS);
1255 }
1256 
1257 /*
1258  * qla2x00_abort_command
1259  *	Abort command aborts a specified IOCB.
1260  *
1261  * Input:
1262  *	ha = adapter block pointer.
1263  *	sp = SB structure pointer.
1264  *
1265  * Returns:
1266  *	qla2x00 local function return status code.
1267  *
1268  * Context:
1269  *	Kernel context.
1270  */
1271 int
1272 qla2x00_abort_command(srb_t *sp)
1273 {
1274 	unsigned long   flags = 0;
1275 	int		rval;
1276 	uint32_t	handle = 0;
1277 	mbx_cmd_t	mc;
1278 	mbx_cmd_t	*mcp = &mc;
1279 	fc_port_t	*fcport = sp->fcport;
1280 	scsi_qla_host_t *vha = fcport->vha;
1281 	struct qla_hw_data *ha = vha->hw;
1282 	struct req_que *req;
1283 	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
1284 
1285 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
1286 	    "Entered %s.\n", __func__);
1287 
1288 	if (vha->flags.qpairs_available && sp->qpair)
1289 		req = sp->qpair->req;
1290 	else
1291 		req = vha->req;
1292 
1293 	spin_lock_irqsave(&ha->hardware_lock, flags);
1294 	for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
1295 		if (req->outstanding_cmds[handle] == sp)
1296 			break;
1297 	}
1298 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1299 
1300 	if (handle == req->num_outstanding_cmds) {
1301 		/* command not found */
1302 		return QLA_FUNCTION_FAILED;
1303 	}
1304 
1305 	mcp->mb[0] = MBC_ABORT_COMMAND;
1306 	if (HAS_EXTENDED_IDS(ha))
1307 		mcp->mb[1] = fcport->loop_id;
1308 	else
1309 		mcp->mb[1] = fcport->loop_id << 8;
1310 	mcp->mb[2] = (uint16_t)handle;
1311 	mcp->mb[3] = (uint16_t)(handle >> 16);
1312 	mcp->mb[6] = (uint16_t)cmd->device->lun;
1313 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1314 	mcp->in_mb = MBX_0;
1315 	mcp->tov = MBX_TOV_SECONDS;
1316 	mcp->flags = 0;
1317 	rval = qla2x00_mailbox_command(vha, mcp);
1318 
1319 	if (rval != QLA_SUCCESS) {
1320 		ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
1321 	} else {
1322 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
1323 		    "Done %s.\n", __func__);
1324 	}
1325 
1326 	return rval;
1327 }
1328 
1329 int
1330 qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
1331 {
1332 	int rval, rval2;
1333 	mbx_cmd_t  mc;
1334 	mbx_cmd_t  *mcp = &mc;
1335 	scsi_qla_host_t *vha;
1336 	struct req_que *req;
1337 	struct rsp_que *rsp;
1338 
1339 	l = l;
1340 	vha = fcport->vha;
1341 
1342 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
1343 	    "Entered %s.\n", __func__);
1344 
1345 	req = vha->hw->req_q_map[0];
1346 	rsp = req->rsp;
1347 	mcp->mb[0] = MBC_ABORT_TARGET;
1348 	mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
1349 	if (HAS_EXTENDED_IDS(vha->hw)) {
1350 		mcp->mb[1] = fcport->loop_id;
1351 		mcp->mb[10] = 0;
1352 		mcp->out_mb |= MBX_10;
1353 	} else {
1354 		mcp->mb[1] = fcport->loop_id << 8;
1355 	}
1356 	mcp->mb[2] = vha->hw->loop_reset_delay;
1357 	mcp->mb[9] = vha->vp_idx;
1358 
1359 	mcp->in_mb = MBX_0;
1360 	mcp->tov = MBX_TOV_SECONDS;
1361 	mcp->flags = 0;
1362 	rval = qla2x00_mailbox_command(vha, mcp);
1363 	if (rval != QLA_SUCCESS) {
1364 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
1365 		    "Failed=%x.\n", rval);
1366 	}
1367 
1368 	/* Issue marker IOCB. */
1369 	rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1370 							MK_SYNC_ID);
1371 	if (rval2 != QLA_SUCCESS) {
1372 		ql_dbg(ql_dbg_mbx, vha, 0x1040,
1373 		    "Failed to issue marker IOCB (%x).\n", rval2);
1374 	} else {
1375 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1376 		    "Done %s.\n", __func__);
1377 	}
1378 
1379 	return rval;
1380 }
1381 
1382 int
1383 qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
1384 {
1385 	int rval, rval2;
1386 	mbx_cmd_t  mc;
1387 	mbx_cmd_t  *mcp = &mc;
1388 	scsi_qla_host_t *vha;
1389 	struct req_que *req;
1390 	struct rsp_que *rsp;
1391 
1392 	vha = fcport->vha;
1393 
1394 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1395 	    "Entered %s.\n", __func__);
1396 
1397 	req = vha->hw->req_q_map[0];
1398 	rsp = req->rsp;
1399 	mcp->mb[0] = MBC_LUN_RESET;
1400 	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
1401 	if (HAS_EXTENDED_IDS(vha->hw))
1402 		mcp->mb[1] = fcport->loop_id;
1403 	else
1404 		mcp->mb[1] = fcport->loop_id << 8;
1405 	mcp->mb[2] = (u32)l;
1406 	mcp->mb[3] = 0;
1407 	mcp->mb[9] = vha->vp_idx;
1408 
1409 	mcp->in_mb = MBX_0;
1410 	mcp->tov = MBX_TOV_SECONDS;
1411 	mcp->flags = 0;
1412 	rval = qla2x00_mailbox_command(vha, mcp);
1413 	if (rval != QLA_SUCCESS) {
1414 		ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
1415 	}
1416 
1417 	/* Issue marker IOCB. */
1418 	rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1419 								MK_SYNC_ID_LUN);
1420 	if (rval2 != QLA_SUCCESS) {
1421 		ql_dbg(ql_dbg_mbx, vha, 0x1044,
1422 		    "Failed to issue marker IOCB (%x).\n", rval2);
1423 	} else {
1424 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1425 		    "Done %s.\n", __func__);
1426 	}
1427 
1428 	return rval;
1429 }
1430 
1431 /*
1432  * qla2x00_get_adapter_id
1433  *	Get adapter ID and topology.
1434  *
1435  * Input:
1436  *	ha = adapter block pointer.
1437  *	id = pointer for loop ID.
1438  *	al_pa = pointer for AL_PA.
1439  *	area = pointer for area.
1440  *	domain = pointer for domain.
1441  *	top = pointer for topology.
1442  *	TARGET_QUEUE_LOCK must be released.
1443  *	ADAPTER_STATE_LOCK must be released.
1444  *
1445  * Returns:
1446  *	qla2x00 local function return status code.
1447  *
1448  * Context:
1449  *	Kernel context.
1450  */
1451 int
1452 qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
1453     uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
1454 {
1455 	int rval;
1456 	mbx_cmd_t mc;
1457 	mbx_cmd_t *mcp = &mc;
1458 
1459 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1460 	    "Entered %s.\n", __func__);
1461 
1462 	mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
1463 	mcp->mb[9] = vha->vp_idx;
1464 	mcp->out_mb = MBX_9|MBX_0;
1465 	mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1466 	if (IS_CNA_CAPABLE(vha->hw))
1467 		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
1468 	if (IS_FWI2_CAPABLE(vha->hw))
1469 		mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
1470 	if (IS_QLA27XX(vha->hw))
1471 		mcp->in_mb |= MBX_15;
1472 	mcp->tov = MBX_TOV_SECONDS;
1473 	mcp->flags = 0;
1474 	rval = qla2x00_mailbox_command(vha, mcp);
1475 	if (mcp->mb[0] == MBS_COMMAND_ERROR)
1476 		rval = QLA_COMMAND_ERROR;
1477 	else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1478 		rval = QLA_INVALID_COMMAND;
1479 
1480 	/* Return data. */
1481 	*id = mcp->mb[1];
1482 	*al_pa = LSB(mcp->mb[2]);
1483 	*area = MSB(mcp->mb[2]);
1484 	*domain	= LSB(mcp->mb[3]);
1485 	*top = mcp->mb[6];
1486 	*sw_cap = mcp->mb[7];
1487 
1488 	if (rval != QLA_SUCCESS) {
1489 		/*EMPTY*/
1490 		ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
1491 	} else {
1492 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1493 		    "Done %s.\n", __func__);
1494 
1495 		if (IS_CNA_CAPABLE(vha->hw)) {
1496 			vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1497 			vha->fcoe_fcf_idx = mcp->mb[10];
1498 			vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1499 			vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1500 			vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1501 			vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1502 			vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1503 			vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1504 		}
1505 		/* If FA-WWN supported */
1506 		if (IS_FAWWN_CAPABLE(vha->hw)) {
1507 			if (mcp->mb[7] & BIT_14) {
1508 				vha->port_name[0] = MSB(mcp->mb[16]);
1509 				vha->port_name[1] = LSB(mcp->mb[16]);
1510 				vha->port_name[2] = MSB(mcp->mb[17]);
1511 				vha->port_name[3] = LSB(mcp->mb[17]);
1512 				vha->port_name[4] = MSB(mcp->mb[18]);
1513 				vha->port_name[5] = LSB(mcp->mb[18]);
1514 				vha->port_name[6] = MSB(mcp->mb[19]);
1515 				vha->port_name[7] = LSB(mcp->mb[19]);
1516 				fc_host_port_name(vha->host) =
1517 				    wwn_to_u64(vha->port_name);
1518 				ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1519 				    "FA-WWN acquired %016llx\n",
1520 				    wwn_to_u64(vha->port_name));
1521 			}
1522 		}
1523 
1524 		if (IS_QLA27XX(vha->hw))
1525 			vha->bbcr = mcp->mb[15];
1526 	}
1527 
1528 	return rval;
1529 }
1530 
1531 /*
1532  * qla2x00_get_retry_cnt
1533  *	Get current firmware login retry count and delay.
1534  *
1535  * Input:
1536  *	ha = adapter block pointer.
1537  *	retry_cnt = pointer to login retry count.
1538  *	tov = pointer to login timeout value.
1539  *
1540  * Returns:
1541  *	qla2x00 local function return status code.
1542  *
1543  * Context:
1544  *	Kernel context.
1545  */
1546 int
1547 qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
1548     uint16_t *r_a_tov)
1549 {
1550 	int rval;
1551 	uint16_t ratov;
1552 	mbx_cmd_t mc;
1553 	mbx_cmd_t *mcp = &mc;
1554 
1555 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1556 	    "Entered %s.\n", __func__);
1557 
1558 	mcp->mb[0] = MBC_GET_RETRY_COUNT;
1559 	mcp->out_mb = MBX_0;
1560 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1561 	mcp->tov = MBX_TOV_SECONDS;
1562 	mcp->flags = 0;
1563 	rval = qla2x00_mailbox_command(vha, mcp);
1564 
1565 	if (rval != QLA_SUCCESS) {
1566 		/*EMPTY*/
1567 		ql_dbg(ql_dbg_mbx, vha, 0x104a,
1568 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1569 	} else {
1570 		/* Convert returned data and check our values. */
1571 		*r_a_tov = mcp->mb[3] / 2;
1572 		ratov = (mcp->mb[3]/2) / 10;  /* mb[3] value is in 100ms */
1573 		if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1574 			/* Update to the larger values */
1575 			*retry_cnt = (uint8_t)mcp->mb[1];
1576 			*tov = ratov;
1577 		}
1578 
1579 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
1580 		    "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
1581 	}
1582 
1583 	return rval;
1584 }
1585 
1586 /*
1587  * qla2x00_init_firmware
1588  *	Initialize adapter firmware.
1589  *
1590  * Input:
1591  *	ha = adapter block pointer.
1592  *	dptr = Initialization control block pointer.
1593  *	size = size of initialization control block.
1594  *	TARGET_QUEUE_LOCK must be released.
1595  *	ADAPTER_STATE_LOCK must be released.
1596  *
1597  * Returns:
1598  *	qla2x00 local function return status code.
1599  *
1600  * Context:
1601  *	Kernel context.
1602  */
1603 int
1604 qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
1605 {
1606 	int rval;
1607 	mbx_cmd_t mc;
1608 	mbx_cmd_t *mcp = &mc;
1609 	struct qla_hw_data *ha = vha->hw;
1610 
1611 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1612 	    "Entered %s.\n", __func__);
1613 
1614 	if (IS_P3P_TYPE(ha) && ql2xdbwr)
1615 		qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
1616 			(0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1617 
1618 	if (ha->flags.npiv_supported)
1619 		mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1620 	else
1621 		mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1622 
1623 	mcp->mb[1] = 0;
1624 	mcp->mb[2] = MSW(ha->init_cb_dma);
1625 	mcp->mb[3] = LSW(ha->init_cb_dma);
1626 	mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1627 	mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
1628 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1629 	if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
1630 		mcp->mb[1] = BIT_0;
1631 		mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1632 		mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1633 		mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1634 		mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1635 		mcp->mb[14] = sizeof(*ha->ex_init_cb);
1636 		mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1637 	}
1638 	/* 1 and 2 should normally be captured. */
1639 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
1640 	if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
1641 		/* mb3 is additional info about the installed SFP. */
1642 		mcp->in_mb  |= MBX_3;
1643 	mcp->buf_size = size;
1644 	mcp->flags = MBX_DMA_OUT;
1645 	mcp->tov = MBX_TOV_SECONDS;
1646 	rval = qla2x00_mailbox_command(vha, mcp);
1647 
1648 	if (rval != QLA_SUCCESS) {
1649 		/*EMPTY*/
1650 		ql_dbg(ql_dbg_mbx, vha, 0x104d,
1651 		    "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1652 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
1653 	} else {
1654 		/*EMPTY*/
1655 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1656 		    "Done %s.\n", __func__);
1657 	}
1658 
1659 	return rval;
1660 }
1661 
1662 
1663 /*
1664  * qla2x00_get_port_database
1665  *	Issue normal/enhanced get port database mailbox command
1666  *	and copy device name as necessary.
1667  *
1668  * Input:
1669  *	ha = adapter state pointer.
1670  *	dev = structure pointer.
1671  *	opt = enhanced cmd option byte.
1672  *
1673  * Returns:
1674  *	qla2x00 local function return status code.
1675  *
1676  * Context:
1677  *	Kernel context.
1678  */
1679 int
1680 qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
1681 {
1682 	int rval;
1683 	mbx_cmd_t mc;
1684 	mbx_cmd_t *mcp = &mc;
1685 	port_database_t *pd;
1686 	struct port_database_24xx *pd24;
1687 	dma_addr_t pd_dma;
1688 	struct qla_hw_data *ha = vha->hw;
1689 
1690 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1691 	    "Entered %s.\n", __func__);
1692 
1693 	pd24 = NULL;
1694 	pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
1695 	if (pd  == NULL) {
1696 		ql_log(ql_log_warn, vha, 0x1050,
1697 		    "Failed to allocate port database structure.\n");
1698 		return QLA_MEMORY_ALLOC_FAILED;
1699 	}
1700 	memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
1701 
1702 	mcp->mb[0] = MBC_GET_PORT_DATABASE;
1703 	if (opt != 0 && !IS_FWI2_CAPABLE(ha))
1704 		mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
1705 	mcp->mb[2] = MSW(pd_dma);
1706 	mcp->mb[3] = LSW(pd_dma);
1707 	mcp->mb[6] = MSW(MSD(pd_dma));
1708 	mcp->mb[7] = LSW(MSD(pd_dma));
1709 	mcp->mb[9] = vha->vp_idx;
1710 	mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1711 	mcp->in_mb = MBX_0;
1712 	if (IS_FWI2_CAPABLE(ha)) {
1713 		mcp->mb[1] = fcport->loop_id;
1714 		mcp->mb[10] = opt;
1715 		mcp->out_mb |= MBX_10|MBX_1;
1716 		mcp->in_mb |= MBX_1;
1717 	} else if (HAS_EXTENDED_IDS(ha)) {
1718 		mcp->mb[1] = fcport->loop_id;
1719 		mcp->mb[10] = opt;
1720 		mcp->out_mb |= MBX_10|MBX_1;
1721 	} else {
1722 		mcp->mb[1] = fcport->loop_id << 8 | opt;
1723 		mcp->out_mb |= MBX_1;
1724 	}
1725 	mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1726 	    PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
1727 	mcp->flags = MBX_DMA_IN;
1728 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1729 	rval = qla2x00_mailbox_command(vha, mcp);
1730 	if (rval != QLA_SUCCESS)
1731 		goto gpd_error_out;
1732 
1733 	if (IS_FWI2_CAPABLE(ha)) {
1734 		uint64_t zero = 0;
1735 		pd24 = (struct port_database_24xx *) pd;
1736 
1737 		/* Check for logged in state. */
1738 		if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1739 		    pd24->last_login_state != PDS_PRLI_COMPLETE) {
1740 			ql_dbg(ql_dbg_mbx, vha, 0x1051,
1741 			    "Unable to verify login-state (%x/%x) for "
1742 			    "loop_id %x.\n", pd24->current_login_state,
1743 			    pd24->last_login_state, fcport->loop_id);
1744 			rval = QLA_FUNCTION_FAILED;
1745 			goto gpd_error_out;
1746 		}
1747 
1748 		if (fcport->loop_id == FC_NO_LOOP_ID ||
1749 		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1750 		     memcmp(fcport->port_name, pd24->port_name, 8))) {
1751 			/* We lost the device mid way. */
1752 			rval = QLA_NOT_LOGGED_IN;
1753 			goto gpd_error_out;
1754 		}
1755 
1756 		/* Names are little-endian. */
1757 		memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1758 		memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1759 
1760 		/* Get port_id of device. */
1761 		fcport->d_id.b.domain = pd24->port_id[0];
1762 		fcport->d_id.b.area = pd24->port_id[1];
1763 		fcport->d_id.b.al_pa = pd24->port_id[2];
1764 		fcport->d_id.b.rsvd_1 = 0;
1765 
1766 		/* If not target must be initiator or unknown type. */
1767 		if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1768 			fcport->port_type = FCT_INITIATOR;
1769 		else
1770 			fcport->port_type = FCT_TARGET;
1771 
1772 		/* Passback COS information. */
1773 		fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1774 				FC_COS_CLASS2 : FC_COS_CLASS3;
1775 
1776 		if (pd24->prli_svc_param_word_3[0] & BIT_7)
1777 			fcport->flags |= FCF_CONF_COMP_SUPPORTED;
1778 	} else {
1779 		uint64_t zero = 0;
1780 
1781 		/* Check for logged in state. */
1782 		if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1783 		    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
1784 			ql_dbg(ql_dbg_mbx, vha, 0x100a,
1785 			    "Unable to verify login-state (%x/%x) - "
1786 			    "portid=%02x%02x%02x.\n", pd->master_state,
1787 			    pd->slave_state, fcport->d_id.b.domain,
1788 			    fcport->d_id.b.area, fcport->d_id.b.al_pa);
1789 			rval = QLA_FUNCTION_FAILED;
1790 			goto gpd_error_out;
1791 		}
1792 
1793 		if (fcport->loop_id == FC_NO_LOOP_ID ||
1794 		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1795 		     memcmp(fcport->port_name, pd->port_name, 8))) {
1796 			/* We lost the device mid way. */
1797 			rval = QLA_NOT_LOGGED_IN;
1798 			goto gpd_error_out;
1799 		}
1800 
1801 		/* Names are little-endian. */
1802 		memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1803 		memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1804 
1805 		/* Get port_id of device. */
1806 		fcport->d_id.b.domain = pd->port_id[0];
1807 		fcport->d_id.b.area = pd->port_id[3];
1808 		fcport->d_id.b.al_pa = pd->port_id[2];
1809 		fcport->d_id.b.rsvd_1 = 0;
1810 
1811 		/* If not target must be initiator or unknown type. */
1812 		if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1813 			fcport->port_type = FCT_INITIATOR;
1814 		else
1815 			fcport->port_type = FCT_TARGET;
1816 
1817 		/* Passback COS information. */
1818 		fcport->supported_classes = (pd->options & BIT_4) ?
1819 		    FC_COS_CLASS2: FC_COS_CLASS3;
1820 	}
1821 
1822 gpd_error_out:
1823 	dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1824 
1825 	if (rval != QLA_SUCCESS) {
1826 		ql_dbg(ql_dbg_mbx, vha, 0x1052,
1827 		    "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1828 		    mcp->mb[0], mcp->mb[1]);
1829 	} else {
1830 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1831 		    "Done %s.\n", __func__);
1832 	}
1833 
1834 	return rval;
1835 }
1836 
1837 /*
1838  * qla2x00_get_firmware_state
1839  *	Get adapter firmware state.
1840  *
1841  * Input:
1842  *	ha = adapter block pointer.
1843  *	dptr = pointer for firmware state.
1844  *	TARGET_QUEUE_LOCK must be released.
1845  *	ADAPTER_STATE_LOCK must be released.
1846  *
1847  * Returns:
1848  *	qla2x00 local function return status code.
1849  *
1850  * Context:
1851  *	Kernel context.
1852  */
1853 int
1854 qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
1855 {
1856 	int rval;
1857 	mbx_cmd_t mc;
1858 	mbx_cmd_t *mcp = &mc;
1859 
1860 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1861 	    "Entered %s.\n", __func__);
1862 
1863 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1864 	mcp->out_mb = MBX_0;
1865 	if (IS_FWI2_CAPABLE(vha->hw))
1866 		mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1867 	else
1868 		mcp->in_mb = MBX_1|MBX_0;
1869 	mcp->tov = MBX_TOV_SECONDS;
1870 	mcp->flags = 0;
1871 	rval = qla2x00_mailbox_command(vha, mcp);
1872 
1873 	/* Return firmware states. */
1874 	states[0] = mcp->mb[1];
1875 	if (IS_FWI2_CAPABLE(vha->hw)) {
1876 		states[1] = mcp->mb[2];
1877 		states[2] = mcp->mb[3];  /* SFP info */
1878 		states[3] = mcp->mb[4];
1879 		states[4] = mcp->mb[5];
1880 		states[5] = mcp->mb[6];  /* DPORT status */
1881 	}
1882 
1883 	if (rval != QLA_SUCCESS) {
1884 		/*EMPTY*/
1885 		ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
1886 	} else {
1887 		/*EMPTY*/
1888 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
1889 		    "Done %s.\n", __func__);
1890 	}
1891 
1892 	return rval;
1893 }
1894 
1895 /*
1896  * qla2x00_get_port_name
1897  *	Issue get port name mailbox command.
1898  *	Returned name is in big endian format.
1899  *
1900  * Input:
1901  *	ha = adapter block pointer.
1902  *	loop_id = loop ID of device.
1903  *	name = pointer for name.
1904  *	TARGET_QUEUE_LOCK must be released.
1905  *	ADAPTER_STATE_LOCK must be released.
1906  *
1907  * Returns:
1908  *	qla2x00 local function return status code.
1909  *
1910  * Context:
1911  *	Kernel context.
1912  */
1913 int
1914 qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
1915     uint8_t opt)
1916 {
1917 	int rval;
1918 	mbx_cmd_t mc;
1919 	mbx_cmd_t *mcp = &mc;
1920 
1921 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
1922 	    "Entered %s.\n", __func__);
1923 
1924 	mcp->mb[0] = MBC_GET_PORT_NAME;
1925 	mcp->mb[9] = vha->vp_idx;
1926 	mcp->out_mb = MBX_9|MBX_1|MBX_0;
1927 	if (HAS_EXTENDED_IDS(vha->hw)) {
1928 		mcp->mb[1] = loop_id;
1929 		mcp->mb[10] = opt;
1930 		mcp->out_mb |= MBX_10;
1931 	} else {
1932 		mcp->mb[1] = loop_id << 8 | opt;
1933 	}
1934 
1935 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1936 	mcp->tov = MBX_TOV_SECONDS;
1937 	mcp->flags = 0;
1938 	rval = qla2x00_mailbox_command(vha, mcp);
1939 
1940 	if (rval != QLA_SUCCESS) {
1941 		/*EMPTY*/
1942 		ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
1943 	} else {
1944 		if (name != NULL) {
1945 			/* This function returns name in big endian. */
1946 			name[0] = MSB(mcp->mb[2]);
1947 			name[1] = LSB(mcp->mb[2]);
1948 			name[2] = MSB(mcp->mb[3]);
1949 			name[3] = LSB(mcp->mb[3]);
1950 			name[4] = MSB(mcp->mb[6]);
1951 			name[5] = LSB(mcp->mb[6]);
1952 			name[6] = MSB(mcp->mb[7]);
1953 			name[7] = LSB(mcp->mb[7]);
1954 		}
1955 
1956 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
1957 		    "Done %s.\n", __func__);
1958 	}
1959 
1960 	return rval;
1961 }
1962 
1963 /*
1964  * qla24xx_link_initialization
1965  *	Issue link initialization mailbox command.
1966  *
1967  * Input:
1968  *	ha = adapter block pointer.
1969  *	TARGET_QUEUE_LOCK must be released.
1970  *	ADAPTER_STATE_LOCK must be released.
1971  *
1972  * Returns:
1973  *	qla2x00 local function return status code.
1974  *
1975  * Context:
1976  *	Kernel context.
1977  */
1978 int
1979 qla24xx_link_initialize(scsi_qla_host_t *vha)
1980 {
1981 	int rval;
1982 	mbx_cmd_t mc;
1983 	mbx_cmd_t *mcp = &mc;
1984 
1985 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
1986 	    "Entered %s.\n", __func__);
1987 
1988 	if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
1989 		return QLA_FUNCTION_FAILED;
1990 
1991 	mcp->mb[0] = MBC_LINK_INITIALIZATION;
1992 	mcp->mb[1] = BIT_4;
1993 	if (vha->hw->operating_mode == LOOP)
1994 		mcp->mb[1] |= BIT_6;
1995 	else
1996 		mcp->mb[1] |= BIT_5;
1997 	mcp->mb[2] = 0;
1998 	mcp->mb[3] = 0;
1999 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2000 	mcp->in_mb = MBX_0;
2001 	mcp->tov = MBX_TOV_SECONDS;
2002 	mcp->flags = 0;
2003 	rval = qla2x00_mailbox_command(vha, mcp);
2004 
2005 	if (rval != QLA_SUCCESS) {
2006 		ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
2007 	} else {
2008 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
2009 		    "Done %s.\n", __func__);
2010 	}
2011 
2012 	return rval;
2013 }
2014 
2015 /*
2016  * qla2x00_lip_reset
2017  *	Issue LIP reset mailbox command.
2018  *
2019  * Input:
2020  *	ha = adapter block pointer.
2021  *	TARGET_QUEUE_LOCK must be released.
2022  *	ADAPTER_STATE_LOCK must be released.
2023  *
2024  * Returns:
2025  *	qla2x00 local function return status code.
2026  *
2027  * Context:
2028  *	Kernel context.
2029  */
2030 int
2031 qla2x00_lip_reset(scsi_qla_host_t *vha)
2032 {
2033 	int rval;
2034 	mbx_cmd_t mc;
2035 	mbx_cmd_t *mcp = &mc;
2036 
2037 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
2038 	    "Entered %s.\n", __func__);
2039 
2040 	if (IS_CNA_CAPABLE(vha->hw)) {
2041 		/* Logout across all FCFs. */
2042 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2043 		mcp->mb[1] = BIT_1;
2044 		mcp->mb[2] = 0;
2045 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
2046 	} else if (IS_FWI2_CAPABLE(vha->hw)) {
2047 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2048 		mcp->mb[1] = BIT_6;
2049 		mcp->mb[2] = 0;
2050 		mcp->mb[3] = vha->hw->loop_reset_delay;
2051 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2052 	} else {
2053 		mcp->mb[0] = MBC_LIP_RESET;
2054 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2055 		if (HAS_EXTENDED_IDS(vha->hw)) {
2056 			mcp->mb[1] = 0x00ff;
2057 			mcp->mb[10] = 0;
2058 			mcp->out_mb |= MBX_10;
2059 		} else {
2060 			mcp->mb[1] = 0xff00;
2061 		}
2062 		mcp->mb[2] = vha->hw->loop_reset_delay;
2063 		mcp->mb[3] = 0;
2064 	}
2065 	mcp->in_mb = MBX_0;
2066 	mcp->tov = MBX_TOV_SECONDS;
2067 	mcp->flags = 0;
2068 	rval = qla2x00_mailbox_command(vha, mcp);
2069 
2070 	if (rval != QLA_SUCCESS) {
2071 		/*EMPTY*/
2072 		ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
2073 	} else {
2074 		/*EMPTY*/
2075 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
2076 		    "Done %s.\n", __func__);
2077 	}
2078 
2079 	return rval;
2080 }
2081 
2082 /*
2083  * qla2x00_send_sns
2084  *	Send SNS command.
2085  *
2086  * Input:
2087  *	ha = adapter block pointer.
2088  *	sns = pointer for command.
2089  *	cmd_size = command size.
2090  *	buf_size = response/command size.
2091  *	TARGET_QUEUE_LOCK must be released.
2092  *	ADAPTER_STATE_LOCK must be released.
2093  *
2094  * Returns:
2095  *	qla2x00 local function return status code.
2096  *
2097  * Context:
2098  *	Kernel context.
2099  */
2100 int
2101 qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
2102     uint16_t cmd_size, size_t buf_size)
2103 {
2104 	int rval;
2105 	mbx_cmd_t mc;
2106 	mbx_cmd_t *mcp = &mc;
2107 
2108 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
2109 	    "Entered %s.\n", __func__);
2110 
2111 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
2112 	    "Retry cnt=%d ratov=%d total tov=%d.\n",
2113 	    vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
2114 
2115 	mcp->mb[0] = MBC_SEND_SNS_COMMAND;
2116 	mcp->mb[1] = cmd_size;
2117 	mcp->mb[2] = MSW(sns_phys_address);
2118 	mcp->mb[3] = LSW(sns_phys_address);
2119 	mcp->mb[6] = MSW(MSD(sns_phys_address));
2120 	mcp->mb[7] = LSW(MSD(sns_phys_address));
2121 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2122 	mcp->in_mb = MBX_0|MBX_1;
2123 	mcp->buf_size = buf_size;
2124 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
2125 	mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
2126 	rval = qla2x00_mailbox_command(vha, mcp);
2127 
2128 	if (rval != QLA_SUCCESS) {
2129 		/*EMPTY*/
2130 		ql_dbg(ql_dbg_mbx, vha, 0x105f,
2131 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
2132 		    rval, mcp->mb[0], mcp->mb[1]);
2133 	} else {
2134 		/*EMPTY*/
2135 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
2136 		    "Done %s.\n", __func__);
2137 	}
2138 
2139 	return rval;
2140 }
2141 
2142 int
2143 qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
2144     uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2145 {
2146 	int		rval;
2147 
2148 	struct logio_entry_24xx *lg;
2149 	dma_addr_t	lg_dma;
2150 	uint32_t	iop[2];
2151 	struct qla_hw_data *ha = vha->hw;
2152 	struct req_que *req;
2153 
2154 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
2155 	    "Entered %s.\n", __func__);
2156 
2157 	if (vha->vp_idx && vha->qpair)
2158 		req = vha->qpair->req;
2159 	else
2160 		req = ha->req_q_map[0];
2161 
2162 	lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2163 	if (lg == NULL) {
2164 		ql_log(ql_log_warn, vha, 0x1062,
2165 		    "Failed to allocate login IOCB.\n");
2166 		return QLA_MEMORY_ALLOC_FAILED;
2167 	}
2168 	memset(lg, 0, sizeof(struct logio_entry_24xx));
2169 
2170 	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2171 	lg->entry_count = 1;
2172 	lg->handle = MAKE_HANDLE(req->id, lg->handle);
2173 	lg->nport_handle = cpu_to_le16(loop_id);
2174 	lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
2175 	if (opt & BIT_0)
2176 		lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
2177 	if (opt & BIT_1)
2178 		lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
2179 	lg->port_id[0] = al_pa;
2180 	lg->port_id[1] = area;
2181 	lg->port_id[2] = domain;
2182 	lg->vp_index = vha->vp_idx;
2183 	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2184 	    (ha->r_a_tov / 10 * 2) + 2);
2185 	if (rval != QLA_SUCCESS) {
2186 		ql_dbg(ql_dbg_mbx, vha, 0x1063,
2187 		    "Failed to issue login IOCB (%x).\n", rval);
2188 	} else if (lg->entry_status != 0) {
2189 		ql_dbg(ql_dbg_mbx, vha, 0x1064,
2190 		    "Failed to complete IOCB -- error status (%x).\n",
2191 		    lg->entry_status);
2192 		rval = QLA_FUNCTION_FAILED;
2193 	} else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
2194 		iop[0] = le32_to_cpu(lg->io_parameter[0]);
2195 		iop[1] = le32_to_cpu(lg->io_parameter[1]);
2196 
2197 		ql_dbg(ql_dbg_mbx, vha, 0x1065,
2198 		    "Failed to complete IOCB -- completion  status (%x) "
2199 		    "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2200 		    iop[0], iop[1]);
2201 
2202 		switch (iop[0]) {
2203 		case LSC_SCODE_PORTID_USED:
2204 			mb[0] = MBS_PORT_ID_USED;
2205 			mb[1] = LSW(iop[1]);
2206 			break;
2207 		case LSC_SCODE_NPORT_USED:
2208 			mb[0] = MBS_LOOP_ID_USED;
2209 			break;
2210 		case LSC_SCODE_NOLINK:
2211 		case LSC_SCODE_NOIOCB:
2212 		case LSC_SCODE_NOXCB:
2213 		case LSC_SCODE_CMD_FAILED:
2214 		case LSC_SCODE_NOFABRIC:
2215 		case LSC_SCODE_FW_NOT_READY:
2216 		case LSC_SCODE_NOT_LOGGED_IN:
2217 		case LSC_SCODE_NOPCB:
2218 		case LSC_SCODE_ELS_REJECT:
2219 		case LSC_SCODE_CMD_PARAM_ERR:
2220 		case LSC_SCODE_NONPORT:
2221 		case LSC_SCODE_LOGGED_IN:
2222 		case LSC_SCODE_NOFLOGI_ACC:
2223 		default:
2224 			mb[0] = MBS_COMMAND_ERROR;
2225 			break;
2226 		}
2227 	} else {
2228 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
2229 		    "Done %s.\n", __func__);
2230 
2231 		iop[0] = le32_to_cpu(lg->io_parameter[0]);
2232 
2233 		mb[0] = MBS_COMMAND_COMPLETE;
2234 		mb[1] = 0;
2235 		if (iop[0] & BIT_4) {
2236 			if (iop[0] & BIT_8)
2237 				mb[1] |= BIT_1;
2238 		} else
2239 			mb[1] = BIT_0;
2240 
2241 		/* Passback COS information. */
2242 		mb[10] = 0;
2243 		if (lg->io_parameter[7] || lg->io_parameter[8])
2244 			mb[10] |= BIT_0;	/* Class 2. */
2245 		if (lg->io_parameter[9] || lg->io_parameter[10])
2246 			mb[10] |= BIT_1;	/* Class 3. */
2247 		if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
2248 			mb[10] |= BIT_7;	/* Confirmed Completion
2249 						 * Allowed
2250 						 */
2251 	}
2252 
2253 	dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2254 
2255 	return rval;
2256 }
2257 
2258 /*
2259  * qla2x00_login_fabric
2260  *	Issue login fabric port mailbox command.
2261  *
2262  * Input:
2263  *	ha = adapter block pointer.
2264  *	loop_id = device loop ID.
2265  *	domain = device domain.
2266  *	area = device area.
2267  *	al_pa = device AL_PA.
2268  *	status = pointer for return status.
2269  *	opt = command options.
2270  *	TARGET_QUEUE_LOCK must be released.
2271  *	ADAPTER_STATE_LOCK must be released.
2272  *
2273  * Returns:
2274  *	qla2x00 local function return status code.
2275  *
2276  * Context:
2277  *	Kernel context.
2278  */
2279 int
2280 qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
2281     uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2282 {
2283 	int rval;
2284 	mbx_cmd_t mc;
2285 	mbx_cmd_t *mcp = &mc;
2286 	struct qla_hw_data *ha = vha->hw;
2287 
2288 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2289 	    "Entered %s.\n", __func__);
2290 
2291 	mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2292 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2293 	if (HAS_EXTENDED_IDS(ha)) {
2294 		mcp->mb[1] = loop_id;
2295 		mcp->mb[10] = opt;
2296 		mcp->out_mb |= MBX_10;
2297 	} else {
2298 		mcp->mb[1] = (loop_id << 8) | opt;
2299 	}
2300 	mcp->mb[2] = domain;
2301 	mcp->mb[3] = area << 8 | al_pa;
2302 
2303 	mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2304 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2305 	mcp->flags = 0;
2306 	rval = qla2x00_mailbox_command(vha, mcp);
2307 
2308 	/* Return mailbox statuses. */
2309 	if (mb != NULL) {
2310 		mb[0] = mcp->mb[0];
2311 		mb[1] = mcp->mb[1];
2312 		mb[2] = mcp->mb[2];
2313 		mb[6] = mcp->mb[6];
2314 		mb[7] = mcp->mb[7];
2315 		/* COS retrieved from Get-Port-Database mailbox command. */
2316 		mb[10] = 0;
2317 	}
2318 
2319 	if (rval != QLA_SUCCESS) {
2320 		/* RLU tmp code: need to change main mailbox_command function to
2321 		 * return ok even when the mailbox completion value is not
2322 		 * SUCCESS. The caller needs to be responsible to interpret
2323 		 * the return values of this mailbox command if we're not
2324 		 * to change too much of the existing code.
2325 		 */
2326 		if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2327 		    mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2328 		    mcp->mb[0] == 0x4006)
2329 			rval = QLA_SUCCESS;
2330 
2331 		/*EMPTY*/
2332 		ql_dbg(ql_dbg_mbx, vha, 0x1068,
2333 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2334 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
2335 	} else {
2336 		/*EMPTY*/
2337 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2338 		    "Done %s.\n", __func__);
2339 	}
2340 
2341 	return rval;
2342 }
2343 
2344 /*
2345  * qla2x00_login_local_device
2346  *           Issue login loop port mailbox command.
2347  *
2348  * Input:
2349  *           ha = adapter block pointer.
2350  *           loop_id = device loop ID.
2351  *           opt = command options.
2352  *
2353  * Returns:
2354  *            Return status code.
2355  *
2356  * Context:
2357  *            Kernel context.
2358  *
2359  */
2360 int
2361 qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
2362     uint16_t *mb_ret, uint8_t opt)
2363 {
2364 	int rval;
2365 	mbx_cmd_t mc;
2366 	mbx_cmd_t *mcp = &mc;
2367 	struct qla_hw_data *ha = vha->hw;
2368 
2369 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2370 	    "Entered %s.\n", __func__);
2371 
2372 	if (IS_FWI2_CAPABLE(ha))
2373 		return qla24xx_login_fabric(vha, fcport->loop_id,
2374 		    fcport->d_id.b.domain, fcport->d_id.b.area,
2375 		    fcport->d_id.b.al_pa, mb_ret, opt);
2376 
2377 	mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2378 	if (HAS_EXTENDED_IDS(ha))
2379 		mcp->mb[1] = fcport->loop_id;
2380 	else
2381 		mcp->mb[1] = fcport->loop_id << 8;
2382 	mcp->mb[2] = opt;
2383 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2384  	mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2385 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2386 	mcp->flags = 0;
2387 	rval = qla2x00_mailbox_command(vha, mcp);
2388 
2389  	/* Return mailbox statuses. */
2390  	if (mb_ret != NULL) {
2391  		mb_ret[0] = mcp->mb[0];
2392  		mb_ret[1] = mcp->mb[1];
2393  		mb_ret[6] = mcp->mb[6];
2394  		mb_ret[7] = mcp->mb[7];
2395  	}
2396 
2397 	if (rval != QLA_SUCCESS) {
2398  		/* AV tmp code: need to change main mailbox_command function to
2399  		 * return ok even when the mailbox completion value is not
2400  		 * SUCCESS. The caller needs to be responsible to interpret
2401  		 * the return values of this mailbox command if we're not
2402  		 * to change too much of the existing code.
2403  		 */
2404  		if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2405  			rval = QLA_SUCCESS;
2406 
2407 		ql_dbg(ql_dbg_mbx, vha, 0x106b,
2408 		    "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2409 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
2410 	} else {
2411 		/*EMPTY*/
2412 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2413 		    "Done %s.\n", __func__);
2414 	}
2415 
2416 	return (rval);
2417 }
2418 
2419 int
2420 qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
2421     uint8_t area, uint8_t al_pa)
2422 {
2423 	int		rval;
2424 	struct logio_entry_24xx *lg;
2425 	dma_addr_t	lg_dma;
2426 	struct qla_hw_data *ha = vha->hw;
2427 	struct req_que *req;
2428 
2429 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2430 	    "Entered %s.\n", __func__);
2431 
2432 	lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2433 	if (lg == NULL) {
2434 		ql_log(ql_log_warn, vha, 0x106e,
2435 		    "Failed to allocate logout IOCB.\n");
2436 		return QLA_MEMORY_ALLOC_FAILED;
2437 	}
2438 	memset(lg, 0, sizeof(struct logio_entry_24xx));
2439 
2440 	req = vha->req;
2441 	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2442 	lg->entry_count = 1;
2443 	lg->handle = MAKE_HANDLE(req->id, lg->handle);
2444 	lg->nport_handle = cpu_to_le16(loop_id);
2445 	lg->control_flags =
2446 	    cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
2447 		LCF_FREE_NPORT);
2448 	lg->port_id[0] = al_pa;
2449 	lg->port_id[1] = area;
2450 	lg->port_id[2] = domain;
2451 	lg->vp_index = vha->vp_idx;
2452 	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2453 	    (ha->r_a_tov / 10 * 2) + 2);
2454 	if (rval != QLA_SUCCESS) {
2455 		ql_dbg(ql_dbg_mbx, vha, 0x106f,
2456 		    "Failed to issue logout IOCB (%x).\n", rval);
2457 	} else if (lg->entry_status != 0) {
2458 		ql_dbg(ql_dbg_mbx, vha, 0x1070,
2459 		    "Failed to complete IOCB -- error status (%x).\n",
2460 		    lg->entry_status);
2461 		rval = QLA_FUNCTION_FAILED;
2462 	} else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
2463 		ql_dbg(ql_dbg_mbx, vha, 0x1071,
2464 		    "Failed to complete IOCB -- completion status (%x) "
2465 		    "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2466 		    le32_to_cpu(lg->io_parameter[0]),
2467 		    le32_to_cpu(lg->io_parameter[1]));
2468 	} else {
2469 		/*EMPTY*/
2470 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2471 		    "Done %s.\n", __func__);
2472 	}
2473 
2474 	dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2475 
2476 	return rval;
2477 }
2478 
2479 /*
2480  * qla2x00_fabric_logout
2481  *	Issue logout fabric port mailbox command.
2482  *
2483  * Input:
2484  *	ha = adapter block pointer.
2485  *	loop_id = device loop ID.
2486  *	TARGET_QUEUE_LOCK must be released.
2487  *	ADAPTER_STATE_LOCK must be released.
2488  *
2489  * Returns:
2490  *	qla2x00 local function return status code.
2491  *
2492  * Context:
2493  *	Kernel context.
2494  */
2495 int
2496 qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
2497     uint8_t area, uint8_t al_pa)
2498 {
2499 	int rval;
2500 	mbx_cmd_t mc;
2501 	mbx_cmd_t *mcp = &mc;
2502 
2503 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2504 	    "Entered %s.\n", __func__);
2505 
2506 	mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2507 	mcp->out_mb = MBX_1|MBX_0;
2508 	if (HAS_EXTENDED_IDS(vha->hw)) {
2509 		mcp->mb[1] = loop_id;
2510 		mcp->mb[10] = 0;
2511 		mcp->out_mb |= MBX_10;
2512 	} else {
2513 		mcp->mb[1] = loop_id << 8;
2514 	}
2515 
2516 	mcp->in_mb = MBX_1|MBX_0;
2517 	mcp->tov = MBX_TOV_SECONDS;
2518 	mcp->flags = 0;
2519 	rval = qla2x00_mailbox_command(vha, mcp);
2520 
2521 	if (rval != QLA_SUCCESS) {
2522 		/*EMPTY*/
2523 		ql_dbg(ql_dbg_mbx, vha, 0x1074,
2524 		    "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
2525 	} else {
2526 		/*EMPTY*/
2527 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2528 		    "Done %s.\n", __func__);
2529 	}
2530 
2531 	return rval;
2532 }
2533 
2534 /*
2535  * qla2x00_full_login_lip
2536  *	Issue full login LIP mailbox command.
2537  *
2538  * Input:
2539  *	ha = adapter block pointer.
2540  *	TARGET_QUEUE_LOCK must be released.
2541  *	ADAPTER_STATE_LOCK must be released.
2542  *
2543  * Returns:
2544  *	qla2x00 local function return status code.
2545  *
2546  * Context:
2547  *	Kernel context.
2548  */
2549 int
2550 qla2x00_full_login_lip(scsi_qla_host_t *vha)
2551 {
2552 	int rval;
2553 	mbx_cmd_t mc;
2554 	mbx_cmd_t *mcp = &mc;
2555 
2556 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2557 	    "Entered %s.\n", __func__);
2558 
2559 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2560 	mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
2561 	mcp->mb[2] = 0;
2562 	mcp->mb[3] = 0;
2563 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2564 	mcp->in_mb = MBX_0;
2565 	mcp->tov = MBX_TOV_SECONDS;
2566 	mcp->flags = 0;
2567 	rval = qla2x00_mailbox_command(vha, mcp);
2568 
2569 	if (rval != QLA_SUCCESS) {
2570 		/*EMPTY*/
2571 		ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
2572 	} else {
2573 		/*EMPTY*/
2574 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2575 		    "Done %s.\n", __func__);
2576 	}
2577 
2578 	return rval;
2579 }
2580 
2581 /*
2582  * qla2x00_get_id_list
2583  *
2584  * Input:
2585  *	ha = adapter block pointer.
2586  *
2587  * Returns:
2588  *	qla2x00 local function return status code.
2589  *
2590  * Context:
2591  *	Kernel context.
2592  */
2593 int
2594 qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
2595     uint16_t *entries)
2596 {
2597 	int rval;
2598 	mbx_cmd_t mc;
2599 	mbx_cmd_t *mcp = &mc;
2600 
2601 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2602 	    "Entered %s.\n", __func__);
2603 
2604 	if (id_list == NULL)
2605 		return QLA_FUNCTION_FAILED;
2606 
2607 	mcp->mb[0] = MBC_GET_ID_LIST;
2608 	mcp->out_mb = MBX_0;
2609 	if (IS_FWI2_CAPABLE(vha->hw)) {
2610 		mcp->mb[2] = MSW(id_list_dma);
2611 		mcp->mb[3] = LSW(id_list_dma);
2612 		mcp->mb[6] = MSW(MSD(id_list_dma));
2613 		mcp->mb[7] = LSW(MSD(id_list_dma));
2614 		mcp->mb[8] = 0;
2615 		mcp->mb[9] = vha->vp_idx;
2616 		mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
2617 	} else {
2618 		mcp->mb[1] = MSW(id_list_dma);
2619 		mcp->mb[2] = LSW(id_list_dma);
2620 		mcp->mb[3] = MSW(MSD(id_list_dma));
2621 		mcp->mb[6] = LSW(MSD(id_list_dma));
2622 		mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2623 	}
2624 	mcp->in_mb = MBX_1|MBX_0;
2625 	mcp->tov = MBX_TOV_SECONDS;
2626 	mcp->flags = 0;
2627 	rval = qla2x00_mailbox_command(vha, mcp);
2628 
2629 	if (rval != QLA_SUCCESS) {
2630 		/*EMPTY*/
2631 		ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
2632 	} else {
2633 		*entries = mcp->mb[1];
2634 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2635 		    "Done %s.\n", __func__);
2636 	}
2637 
2638 	return rval;
2639 }
2640 
2641 /*
2642  * qla2x00_get_resource_cnts
2643  *	Get current firmware resource counts.
2644  *
2645  * Input:
2646  *	ha = adapter block pointer.
2647  *
2648  * Returns:
2649  *	qla2x00 local function return status code.
2650  *
2651  * Context:
2652  *	Kernel context.
2653  */
2654 int
2655 qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
2656 {
2657 	struct qla_hw_data *ha = vha->hw;
2658 	int rval;
2659 	mbx_cmd_t mc;
2660 	mbx_cmd_t *mcp = &mc;
2661 
2662 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2663 	    "Entered %s.\n", __func__);
2664 
2665 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2666 	mcp->out_mb = MBX_0;
2667 	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2668 	if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
2669 		mcp->in_mb |= MBX_12;
2670 	mcp->tov = MBX_TOV_SECONDS;
2671 	mcp->flags = 0;
2672 	rval = qla2x00_mailbox_command(vha, mcp);
2673 
2674 	if (rval != QLA_SUCCESS) {
2675 		/*EMPTY*/
2676 		ql_dbg(ql_dbg_mbx, vha, 0x107d,
2677 		    "Failed mb[0]=%x.\n", mcp->mb[0]);
2678 	} else {
2679 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
2680 		    "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2681 		    "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2682 		    mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2683 		    mcp->mb[11], mcp->mb[12]);
2684 
2685 		ha->orig_fw_tgt_xcb_count =  mcp->mb[1];
2686 		ha->cur_fw_tgt_xcb_count = mcp->mb[2];
2687 		ha->cur_fw_xcb_count = mcp->mb[3];
2688 		ha->orig_fw_xcb_count = mcp->mb[6];
2689 		ha->cur_fw_iocb_count = mcp->mb[7];
2690 		ha->orig_fw_iocb_count = mcp->mb[10];
2691 		if (ha->flags.npiv_supported)
2692 			ha->max_npiv_vports = mcp->mb[11];
2693 		if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
2694 			ha->fw_max_fcf_count = mcp->mb[12];
2695 	}
2696 
2697 	return (rval);
2698 }
2699 
2700 /*
2701  * qla2x00_get_fcal_position_map
2702  *	Get FCAL (LILP) position map using mailbox command
2703  *
2704  * Input:
2705  *	ha = adapter state pointer.
2706  *	pos_map = buffer pointer (can be NULL).
2707  *
2708  * Returns:
2709  *	qla2x00 local function return status code.
2710  *
2711  * Context:
2712  *	Kernel context.
2713  */
2714 int
2715 qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
2716 {
2717 	int rval;
2718 	mbx_cmd_t mc;
2719 	mbx_cmd_t *mcp = &mc;
2720 	char *pmap;
2721 	dma_addr_t pmap_dma;
2722 	struct qla_hw_data *ha = vha->hw;
2723 
2724 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2725 	    "Entered %s.\n", __func__);
2726 
2727 	pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
2728 	if (pmap  == NULL) {
2729 		ql_log(ql_log_warn, vha, 0x1080,
2730 		    "Memory alloc failed.\n");
2731 		return QLA_MEMORY_ALLOC_FAILED;
2732 	}
2733 	memset(pmap, 0, FCAL_MAP_SIZE);
2734 
2735 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2736 	mcp->mb[2] = MSW(pmap_dma);
2737 	mcp->mb[3] = LSW(pmap_dma);
2738 	mcp->mb[6] = MSW(MSD(pmap_dma));
2739 	mcp->mb[7] = LSW(MSD(pmap_dma));
2740 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2741 	mcp->in_mb = MBX_1|MBX_0;
2742 	mcp->buf_size = FCAL_MAP_SIZE;
2743 	mcp->flags = MBX_DMA_IN;
2744 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2745 	rval = qla2x00_mailbox_command(vha, mcp);
2746 
2747 	if (rval == QLA_SUCCESS) {
2748 		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
2749 		    "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2750 		    mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2751 		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2752 		    pmap, pmap[0] + 1);
2753 
2754 		if (pos_map)
2755 			memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2756 	}
2757 	dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2758 
2759 	if (rval != QLA_SUCCESS) {
2760 		ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
2761 	} else {
2762 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2763 		    "Done %s.\n", __func__);
2764 	}
2765 
2766 	return rval;
2767 }
2768 
2769 /*
2770  * qla2x00_get_link_status
2771  *
2772  * Input:
2773  *	ha = adapter block pointer.
2774  *	loop_id = device loop ID.
2775  *	ret_buf = pointer to link status return buffer.
2776  *
2777  * Returns:
2778  *	0 = success.
2779  *	BIT_0 = mem alloc error.
2780  *	BIT_1 = mailbox error.
2781  */
2782 int
2783 qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
2784     struct link_statistics *stats, dma_addr_t stats_dma)
2785 {
2786 	int rval;
2787 	mbx_cmd_t mc;
2788 	mbx_cmd_t *mcp = &mc;
2789 	uint32_t *iter = (void *)stats;
2790 	ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);
2791 	struct qla_hw_data *ha = vha->hw;
2792 
2793 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2794 	    "Entered %s.\n", __func__);
2795 
2796 	mcp->mb[0] = MBC_GET_LINK_STATUS;
2797 	mcp->mb[2] = MSW(LSD(stats_dma));
2798 	mcp->mb[3] = LSW(LSD(stats_dma));
2799 	mcp->mb[6] = MSW(MSD(stats_dma));
2800 	mcp->mb[7] = LSW(MSD(stats_dma));
2801 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2802 	mcp->in_mb = MBX_0;
2803 	if (IS_FWI2_CAPABLE(ha)) {
2804 		mcp->mb[1] = loop_id;
2805 		mcp->mb[4] = 0;
2806 		mcp->mb[10] = 0;
2807 		mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2808 		mcp->in_mb |= MBX_1;
2809 	} else if (HAS_EXTENDED_IDS(ha)) {
2810 		mcp->mb[1] = loop_id;
2811 		mcp->mb[10] = 0;
2812 		mcp->out_mb |= MBX_10|MBX_1;
2813 	} else {
2814 		mcp->mb[1] = loop_id << 8;
2815 		mcp->out_mb |= MBX_1;
2816 	}
2817 	mcp->tov = MBX_TOV_SECONDS;
2818 	mcp->flags = IOCTL_CMD;
2819 	rval = qla2x00_mailbox_command(vha, mcp);
2820 
2821 	if (rval == QLA_SUCCESS) {
2822 		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2823 			ql_dbg(ql_dbg_mbx, vha, 0x1085,
2824 			    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2825 			rval = QLA_FUNCTION_FAILED;
2826 		} else {
2827 			/* Re-endianize - firmware data is le32. */
2828 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2829 			    "Done %s.\n", __func__);
2830 			for ( ; dwords--; iter++)
2831 				le32_to_cpus(iter);
2832 		}
2833 	} else {
2834 		/* Failed. */
2835 		ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
2836 	}
2837 
2838 	return rval;
2839 }
2840 
2841 int
2842 qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
2843     dma_addr_t stats_dma, uint16_t options)
2844 {
2845 	int rval;
2846 	mbx_cmd_t mc;
2847 	mbx_cmd_t *mcp = &mc;
2848 	uint32_t *iter, dwords;
2849 
2850 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2851 	    "Entered %s.\n", __func__);
2852 
2853 	memset(&mc, 0, sizeof(mc));
2854 	mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
2855 	mc.mb[2] = MSW(stats_dma);
2856 	mc.mb[3] = LSW(stats_dma);
2857 	mc.mb[6] = MSW(MSD(stats_dma));
2858 	mc.mb[7] = LSW(MSD(stats_dma));
2859 	mc.mb[8] = sizeof(struct link_statistics) / 4;
2860 	mc.mb[9] = cpu_to_le16(vha->vp_idx);
2861 	mc.mb[10] = cpu_to_le16(options);
2862 
2863 	rval = qla24xx_send_mb_cmd(vha, &mc);
2864 
2865 	if (rval == QLA_SUCCESS) {
2866 		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2867 			ql_dbg(ql_dbg_mbx, vha, 0x1089,
2868 			    "Failed mb[0]=%x.\n", mcp->mb[0]);
2869 			rval = QLA_FUNCTION_FAILED;
2870 		} else {
2871 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
2872 			    "Done %s.\n", __func__);
2873 			/* Re-endianize - firmware data is le32. */
2874 			dwords = sizeof(struct link_statistics) / 4;
2875 			iter = &stats->link_fail_cnt;
2876 			for ( ; dwords--; iter++)
2877 				le32_to_cpus(iter);
2878 		}
2879 	} else {
2880 		/* Failed. */
2881 		ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
2882 	}
2883 
2884 	return rval;
2885 }
2886 
2887 int
2888 qla24xx_abort_command(srb_t *sp)
2889 {
2890 	int		rval;
2891 	unsigned long   flags = 0;
2892 
2893 	struct abort_entry_24xx *abt;
2894 	dma_addr_t	abt_dma;
2895 	uint32_t	handle;
2896 	fc_port_t	*fcport = sp->fcport;
2897 	struct scsi_qla_host *vha = fcport->vha;
2898 	struct qla_hw_data *ha = vha->hw;
2899 	struct req_que *req = vha->req;
2900 
2901 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2902 	    "Entered %s.\n", __func__);
2903 
2904 	if (vha->flags.qpairs_available && sp->qpair)
2905 		req = sp->qpair->req;
2906 
2907 	if (ql2xasynctmfenable)
2908 		return qla24xx_async_abort_command(sp);
2909 
2910 	spin_lock_irqsave(&ha->hardware_lock, flags);
2911 	for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
2912 		if (req->outstanding_cmds[handle] == sp)
2913 			break;
2914 	}
2915 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
2916 	if (handle == req->num_outstanding_cmds) {
2917 		/* Command not found. */
2918 		return QLA_FUNCTION_FAILED;
2919 	}
2920 
2921 	abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2922 	if (abt == NULL) {
2923 		ql_log(ql_log_warn, vha, 0x108d,
2924 		    "Failed to allocate abort IOCB.\n");
2925 		return QLA_MEMORY_ALLOC_FAILED;
2926 	}
2927 	memset(abt, 0, sizeof(struct abort_entry_24xx));
2928 
2929 	abt->entry_type = ABORT_IOCB_TYPE;
2930 	abt->entry_count = 1;
2931 	abt->handle = MAKE_HANDLE(req->id, abt->handle);
2932 	abt->nport_handle = cpu_to_le16(fcport->loop_id);
2933 	abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
2934 	abt->port_id[0] = fcport->d_id.b.al_pa;
2935 	abt->port_id[1] = fcport->d_id.b.area;
2936 	abt->port_id[2] = fcport->d_id.b.domain;
2937 	abt->vp_index = fcport->vha->vp_idx;
2938 
2939 	abt->req_que_no = cpu_to_le16(req->id);
2940 
2941 	rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
2942 	if (rval != QLA_SUCCESS) {
2943 		ql_dbg(ql_dbg_mbx, vha, 0x108e,
2944 		    "Failed to issue IOCB (%x).\n", rval);
2945 	} else if (abt->entry_status != 0) {
2946 		ql_dbg(ql_dbg_mbx, vha, 0x108f,
2947 		    "Failed to complete IOCB -- error status (%x).\n",
2948 		    abt->entry_status);
2949 		rval = QLA_FUNCTION_FAILED;
2950 	} else if (abt->nport_handle != cpu_to_le16(0)) {
2951 		ql_dbg(ql_dbg_mbx, vha, 0x1090,
2952 		    "Failed to complete IOCB -- completion status (%x).\n",
2953 		    le16_to_cpu(abt->nport_handle));
2954 		if (abt->nport_handle == CS_IOCB_ERROR)
2955 			rval = QLA_FUNCTION_PARAMETER_ERROR;
2956 		else
2957 			rval = QLA_FUNCTION_FAILED;
2958 	} else {
2959 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2960 		    "Done %s.\n", __func__);
2961 	}
2962 
2963 	dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2964 
2965 	return rval;
2966 }
2967 
2968 struct tsk_mgmt_cmd {
2969 	union {
2970 		struct tsk_mgmt_entry tsk;
2971 		struct sts_entry_24xx sts;
2972 	} p;
2973 };
2974 
2975 static int
2976 __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2977     uint64_t l, int tag)
2978 {
2979 	int		rval, rval2;
2980 	struct tsk_mgmt_cmd *tsk;
2981 	struct sts_entry_24xx *sts;
2982 	dma_addr_t	tsk_dma;
2983 	scsi_qla_host_t *vha;
2984 	struct qla_hw_data *ha;
2985 	struct req_que *req;
2986 	struct rsp_que *rsp;
2987 	struct qla_qpair *qpair;
2988 
2989 	vha = fcport->vha;
2990 	ha = vha->hw;
2991 	req = vha->req;
2992 
2993 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2994 	    "Entered %s.\n", __func__);
2995 
2996 	if (vha->vp_idx && vha->qpair) {
2997 		/* NPIV port */
2998 		qpair = vha->qpair;
2999 		rsp = qpair->rsp;
3000 		req = qpair->req;
3001 	} else {
3002 		rsp = req->rsp;
3003 	}
3004 
3005 	tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
3006 	if (tsk == NULL) {
3007 		ql_log(ql_log_warn, vha, 0x1093,
3008 		    "Failed to allocate task management IOCB.\n");
3009 		return QLA_MEMORY_ALLOC_FAILED;
3010 	}
3011 	memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
3012 
3013 	tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
3014 	tsk->p.tsk.entry_count = 1;
3015 	tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
3016 	tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
3017 	tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
3018 	tsk->p.tsk.control_flags = cpu_to_le32(type);
3019 	tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
3020 	tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
3021 	tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
3022 	tsk->p.tsk.vp_index = fcport->vha->vp_idx;
3023 	if (type == TCF_LUN_RESET) {
3024 		int_to_scsilun(l, &tsk->p.tsk.lun);
3025 		host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
3026 		    sizeof(tsk->p.tsk.lun));
3027 	}
3028 
3029 	sts = &tsk->p.sts;
3030 	rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
3031 	if (rval != QLA_SUCCESS) {
3032 		ql_dbg(ql_dbg_mbx, vha, 0x1094,
3033 		    "Failed to issue %s reset IOCB (%x).\n", name, rval);
3034 	} else if (sts->entry_status != 0) {
3035 		ql_dbg(ql_dbg_mbx, vha, 0x1095,
3036 		    "Failed to complete IOCB -- error status (%x).\n",
3037 		    sts->entry_status);
3038 		rval = QLA_FUNCTION_FAILED;
3039 	} else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
3040 		ql_dbg(ql_dbg_mbx, vha, 0x1096,
3041 		    "Failed to complete IOCB -- completion status (%x).\n",
3042 		    le16_to_cpu(sts->comp_status));
3043 		rval = QLA_FUNCTION_FAILED;
3044 	} else if (le16_to_cpu(sts->scsi_status) &
3045 	    SS_RESPONSE_INFO_LEN_VALID) {
3046 		if (le32_to_cpu(sts->rsp_data_len) < 4) {
3047 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
3048 			    "Ignoring inconsistent data length -- not enough "
3049 			    "response info (%d).\n",
3050 			    le32_to_cpu(sts->rsp_data_len));
3051 		} else if (sts->data[3]) {
3052 			ql_dbg(ql_dbg_mbx, vha, 0x1098,
3053 			    "Failed to complete IOCB -- response (%x).\n",
3054 			    sts->data[3]);
3055 			rval = QLA_FUNCTION_FAILED;
3056 		}
3057 	}
3058 
3059 	/* Issue marker IOCB. */
3060 	rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
3061 	    type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
3062 	if (rval2 != QLA_SUCCESS) {
3063 		ql_dbg(ql_dbg_mbx, vha, 0x1099,
3064 		    "Failed to issue marker IOCB (%x).\n", rval2);
3065 	} else {
3066 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
3067 		    "Done %s.\n", __func__);
3068 	}
3069 
3070 	dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
3071 
3072 	return rval;
3073 }
3074 
3075 int
3076 qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
3077 {
3078 	struct qla_hw_data *ha = fcport->vha->hw;
3079 
3080 	if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3081 		return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
3082 
3083 	return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
3084 }
3085 
3086 int
3087 qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
3088 {
3089 	struct qla_hw_data *ha = fcport->vha->hw;
3090 
3091 	if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3092 		return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
3093 
3094 	return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
3095 }
3096 
3097 int
3098 qla2x00_system_error(scsi_qla_host_t *vha)
3099 {
3100 	int rval;
3101 	mbx_cmd_t mc;
3102 	mbx_cmd_t *mcp = &mc;
3103 	struct qla_hw_data *ha = vha->hw;
3104 
3105 	if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
3106 		return QLA_FUNCTION_FAILED;
3107 
3108 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
3109 	    "Entered %s.\n", __func__);
3110 
3111 	mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
3112 	mcp->out_mb = MBX_0;
3113 	mcp->in_mb = MBX_0;
3114 	mcp->tov = 5;
3115 	mcp->flags = 0;
3116 	rval = qla2x00_mailbox_command(vha, mcp);
3117 
3118 	if (rval != QLA_SUCCESS) {
3119 		ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
3120 	} else {
3121 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
3122 		    "Done %s.\n", __func__);
3123 	}
3124 
3125 	return rval;
3126 }
3127 
3128 int
3129 qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
3130 {
3131 	int rval;
3132 	mbx_cmd_t mc;
3133 	mbx_cmd_t *mcp = &mc;
3134 
3135 	if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3136 	    !IS_QLA27XX(vha->hw))
3137 		return QLA_FUNCTION_FAILED;
3138 
3139 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
3140 	    "Entered %s.\n", __func__);
3141 
3142 	mcp->mb[0] = MBC_WRITE_SERDES;
3143 	mcp->mb[1] = addr;
3144 	if (IS_QLA2031(vha->hw))
3145 		mcp->mb[2] = data & 0xff;
3146 	else
3147 		mcp->mb[2] = data;
3148 
3149 	mcp->mb[3] = 0;
3150 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3151 	mcp->in_mb = MBX_0;
3152 	mcp->tov = MBX_TOV_SECONDS;
3153 	mcp->flags = 0;
3154 	rval = qla2x00_mailbox_command(vha, mcp);
3155 
3156 	if (rval != QLA_SUCCESS) {
3157 		ql_dbg(ql_dbg_mbx, vha, 0x1183,
3158 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3159 	} else {
3160 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3161 		    "Done %s.\n", __func__);
3162 	}
3163 
3164 	return rval;
3165 }
3166 
3167 int
3168 qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3169 {
3170 	int rval;
3171 	mbx_cmd_t mc;
3172 	mbx_cmd_t *mcp = &mc;
3173 
3174 	if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3175 	    !IS_QLA27XX(vha->hw))
3176 		return QLA_FUNCTION_FAILED;
3177 
3178 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3179 	    "Entered %s.\n", __func__);
3180 
3181 	mcp->mb[0] = MBC_READ_SERDES;
3182 	mcp->mb[1] = addr;
3183 	mcp->mb[3] = 0;
3184 	mcp->out_mb = MBX_3|MBX_1|MBX_0;
3185 	mcp->in_mb = MBX_1|MBX_0;
3186 	mcp->tov = MBX_TOV_SECONDS;
3187 	mcp->flags = 0;
3188 	rval = qla2x00_mailbox_command(vha, mcp);
3189 
3190 	if (IS_QLA2031(vha->hw))
3191 		*data = mcp->mb[1] & 0xff;
3192 	else
3193 		*data = mcp->mb[1];
3194 
3195 	if (rval != QLA_SUCCESS) {
3196 		ql_dbg(ql_dbg_mbx, vha, 0x1186,
3197 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3198 	} else {
3199 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3200 		    "Done %s.\n", __func__);
3201 	}
3202 
3203 	return rval;
3204 }
3205 
3206 int
3207 qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3208 {
3209 	int rval;
3210 	mbx_cmd_t mc;
3211 	mbx_cmd_t *mcp = &mc;
3212 
3213 	if (!IS_QLA8044(vha->hw))
3214 		return QLA_FUNCTION_FAILED;
3215 
3216 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186,
3217 	    "Entered %s.\n", __func__);
3218 
3219 	mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3220 	mcp->mb[1] = HCS_WRITE_SERDES;
3221 	mcp->mb[3] = LSW(addr);
3222 	mcp->mb[4] = MSW(addr);
3223 	mcp->mb[5] = LSW(data);
3224 	mcp->mb[6] = MSW(data);
3225 	mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3226 	mcp->in_mb = MBX_0;
3227 	mcp->tov = MBX_TOV_SECONDS;
3228 	mcp->flags = 0;
3229 	rval = qla2x00_mailbox_command(vha, mcp);
3230 
3231 	if (rval != QLA_SUCCESS) {
3232 		ql_dbg(ql_dbg_mbx, vha, 0x1187,
3233 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3234 	} else {
3235 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3236 		    "Done %s.\n", __func__);
3237 	}
3238 
3239 	return rval;
3240 }
3241 
3242 int
3243 qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3244 {
3245 	int rval;
3246 	mbx_cmd_t mc;
3247 	mbx_cmd_t *mcp = &mc;
3248 
3249 	if (!IS_QLA8044(vha->hw))
3250 		return QLA_FUNCTION_FAILED;
3251 
3252 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3253 	    "Entered %s.\n", __func__);
3254 
3255 	mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3256 	mcp->mb[1] = HCS_READ_SERDES;
3257 	mcp->mb[3] = LSW(addr);
3258 	mcp->mb[4] = MSW(addr);
3259 	mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3260 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
3261 	mcp->tov = MBX_TOV_SECONDS;
3262 	mcp->flags = 0;
3263 	rval = qla2x00_mailbox_command(vha, mcp);
3264 
3265 	*data = mcp->mb[2] << 16 | mcp->mb[1];
3266 
3267 	if (rval != QLA_SUCCESS) {
3268 		ql_dbg(ql_dbg_mbx, vha, 0x118a,
3269 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3270 	} else {
3271 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3272 		    "Done %s.\n", __func__);
3273 	}
3274 
3275 	return rval;
3276 }
3277 
3278 /**
3279  * qla2x00_set_serdes_params() -
3280  * @ha: HA context
3281  *
3282  * Returns
3283  */
3284 int
3285 qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
3286     uint16_t sw_em_2g, uint16_t sw_em_4g)
3287 {
3288 	int rval;
3289 	mbx_cmd_t mc;
3290 	mbx_cmd_t *mcp = &mc;
3291 
3292 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3293 	    "Entered %s.\n", __func__);
3294 
3295 	mcp->mb[0] = MBC_SERDES_PARAMS;
3296 	mcp->mb[1] = BIT_0;
3297 	mcp->mb[2] = sw_em_1g | BIT_15;
3298 	mcp->mb[3] = sw_em_2g | BIT_15;
3299 	mcp->mb[4] = sw_em_4g | BIT_15;
3300 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3301 	mcp->in_mb = MBX_0;
3302 	mcp->tov = MBX_TOV_SECONDS;
3303 	mcp->flags = 0;
3304 	rval = qla2x00_mailbox_command(vha, mcp);
3305 
3306 	if (rval != QLA_SUCCESS) {
3307 		/*EMPTY*/
3308 		ql_dbg(ql_dbg_mbx, vha, 0x109f,
3309 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3310 	} else {
3311 		/*EMPTY*/
3312 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3313 		    "Done %s.\n", __func__);
3314 	}
3315 
3316 	return rval;
3317 }
3318 
3319 int
3320 qla2x00_stop_firmware(scsi_qla_host_t *vha)
3321 {
3322 	int rval;
3323 	mbx_cmd_t mc;
3324 	mbx_cmd_t *mcp = &mc;
3325 
3326 	if (!IS_FWI2_CAPABLE(vha->hw))
3327 		return QLA_FUNCTION_FAILED;
3328 
3329 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3330 	    "Entered %s.\n", __func__);
3331 
3332 	mcp->mb[0] = MBC_STOP_FIRMWARE;
3333 	mcp->mb[1] = 0;
3334 	mcp->out_mb = MBX_1|MBX_0;
3335 	mcp->in_mb = MBX_0;
3336 	mcp->tov = 5;
3337 	mcp->flags = 0;
3338 	rval = qla2x00_mailbox_command(vha, mcp);
3339 
3340 	if (rval != QLA_SUCCESS) {
3341 		ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
3342 		if (mcp->mb[0] == MBS_INVALID_COMMAND)
3343 			rval = QLA_INVALID_COMMAND;
3344 	} else {
3345 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3346 		    "Done %s.\n", __func__);
3347 	}
3348 
3349 	return rval;
3350 }
3351 
3352 int
3353 qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
3354     uint16_t buffers)
3355 {
3356 	int rval;
3357 	mbx_cmd_t mc;
3358 	mbx_cmd_t *mcp = &mc;
3359 
3360 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3361 	    "Entered %s.\n", __func__);
3362 
3363 	if (!IS_FWI2_CAPABLE(vha->hw))
3364 		return QLA_FUNCTION_FAILED;
3365 
3366 	if (unlikely(pci_channel_offline(vha->hw->pdev)))
3367 		return QLA_FUNCTION_FAILED;
3368 
3369 	mcp->mb[0] = MBC_TRACE_CONTROL;
3370 	mcp->mb[1] = TC_EFT_ENABLE;
3371 	mcp->mb[2] = LSW(eft_dma);
3372 	mcp->mb[3] = MSW(eft_dma);
3373 	mcp->mb[4] = LSW(MSD(eft_dma));
3374 	mcp->mb[5] = MSW(MSD(eft_dma));
3375 	mcp->mb[6] = buffers;
3376 	mcp->mb[7] = TC_AEN_DISABLE;
3377 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3378 	mcp->in_mb = MBX_1|MBX_0;
3379 	mcp->tov = MBX_TOV_SECONDS;
3380 	mcp->flags = 0;
3381 	rval = qla2x00_mailbox_command(vha, mcp);
3382 	if (rval != QLA_SUCCESS) {
3383 		ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3384 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
3385 		    rval, mcp->mb[0], mcp->mb[1]);
3386 	} else {
3387 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3388 		    "Done %s.\n", __func__);
3389 	}
3390 
3391 	return rval;
3392 }
3393 
3394 int
3395 qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
3396 {
3397 	int rval;
3398 	mbx_cmd_t mc;
3399 	mbx_cmd_t *mcp = &mc;
3400 
3401 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3402 	    "Entered %s.\n", __func__);
3403 
3404 	if (!IS_FWI2_CAPABLE(vha->hw))
3405 		return QLA_FUNCTION_FAILED;
3406 
3407 	if (unlikely(pci_channel_offline(vha->hw->pdev)))
3408 		return QLA_FUNCTION_FAILED;
3409 
3410 	mcp->mb[0] = MBC_TRACE_CONTROL;
3411 	mcp->mb[1] = TC_EFT_DISABLE;
3412 	mcp->out_mb = MBX_1|MBX_0;
3413 	mcp->in_mb = MBX_1|MBX_0;
3414 	mcp->tov = MBX_TOV_SECONDS;
3415 	mcp->flags = 0;
3416 	rval = qla2x00_mailbox_command(vha, mcp);
3417 	if (rval != QLA_SUCCESS) {
3418 		ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3419 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
3420 		    rval, mcp->mb[0], mcp->mb[1]);
3421 	} else {
3422 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3423 		    "Done %s.\n", __func__);
3424 	}
3425 
3426 	return rval;
3427 }
3428 
3429 int
3430 qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
3431     uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3432 {
3433 	int rval;
3434 	mbx_cmd_t mc;
3435 	mbx_cmd_t *mcp = &mc;
3436 
3437 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3438 	    "Entered %s.\n", __func__);
3439 
3440 	if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
3441 	    !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
3442 		return QLA_FUNCTION_FAILED;
3443 
3444 	if (unlikely(pci_channel_offline(vha->hw->pdev)))
3445 		return QLA_FUNCTION_FAILED;
3446 
3447 	mcp->mb[0] = MBC_TRACE_CONTROL;
3448 	mcp->mb[1] = TC_FCE_ENABLE;
3449 	mcp->mb[2] = LSW(fce_dma);
3450 	mcp->mb[3] = MSW(fce_dma);
3451 	mcp->mb[4] = LSW(MSD(fce_dma));
3452 	mcp->mb[5] = MSW(MSD(fce_dma));
3453 	mcp->mb[6] = buffers;
3454 	mcp->mb[7] = TC_AEN_DISABLE;
3455 	mcp->mb[8] = 0;
3456 	mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3457 	mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3458 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3459 	    MBX_1|MBX_0;
3460 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3461 	mcp->tov = MBX_TOV_SECONDS;
3462 	mcp->flags = 0;
3463 	rval = qla2x00_mailbox_command(vha, mcp);
3464 	if (rval != QLA_SUCCESS) {
3465 		ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3466 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
3467 		    rval, mcp->mb[0], mcp->mb[1]);
3468 	} else {
3469 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3470 		    "Done %s.\n", __func__);
3471 
3472 		if (mb)
3473 			memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3474 		if (dwords)
3475 			*dwords = buffers;
3476 	}
3477 
3478 	return rval;
3479 }
3480 
3481 int
3482 qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
3483 {
3484 	int rval;
3485 	mbx_cmd_t mc;
3486 	mbx_cmd_t *mcp = &mc;
3487 
3488 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3489 	    "Entered %s.\n", __func__);
3490 
3491 	if (!IS_FWI2_CAPABLE(vha->hw))
3492 		return QLA_FUNCTION_FAILED;
3493 
3494 	if (unlikely(pci_channel_offline(vha->hw->pdev)))
3495 		return QLA_FUNCTION_FAILED;
3496 
3497 	mcp->mb[0] = MBC_TRACE_CONTROL;
3498 	mcp->mb[1] = TC_FCE_DISABLE;
3499 	mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3500 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
3501 	mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3502 	    MBX_1|MBX_0;
3503 	mcp->tov = MBX_TOV_SECONDS;
3504 	mcp->flags = 0;
3505 	rval = qla2x00_mailbox_command(vha, mcp);
3506 	if (rval != QLA_SUCCESS) {
3507 		ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3508 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
3509 		    rval, mcp->mb[0], mcp->mb[1]);
3510 	} else {
3511 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3512 		    "Done %s.\n", __func__);
3513 
3514 		if (wr)
3515 			*wr = (uint64_t) mcp->mb[5] << 48 |
3516 			    (uint64_t) mcp->mb[4] << 32 |
3517 			    (uint64_t) mcp->mb[3] << 16 |
3518 			    (uint64_t) mcp->mb[2];
3519 		if (rd)
3520 			*rd = (uint64_t) mcp->mb[9] << 48 |
3521 			    (uint64_t) mcp->mb[8] << 32 |
3522 			    (uint64_t) mcp->mb[7] << 16 |
3523 			    (uint64_t) mcp->mb[6];
3524 	}
3525 
3526 	return rval;
3527 }
3528 
3529 int
3530 qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3531 	uint16_t *port_speed, uint16_t *mb)
3532 {
3533 	int rval;
3534 	mbx_cmd_t mc;
3535 	mbx_cmd_t *mcp = &mc;
3536 
3537 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3538 	    "Entered %s.\n", __func__);
3539 
3540 	if (!IS_IIDMA_CAPABLE(vha->hw))
3541 		return QLA_FUNCTION_FAILED;
3542 
3543 	mcp->mb[0] = MBC_PORT_PARAMS;
3544 	mcp->mb[1] = loop_id;
3545 	mcp->mb[2] = mcp->mb[3] = 0;
3546 	mcp->mb[9] = vha->vp_idx;
3547 	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3548 	mcp->in_mb = MBX_3|MBX_1|MBX_0;
3549 	mcp->tov = MBX_TOV_SECONDS;
3550 	mcp->flags = 0;
3551 	rval = qla2x00_mailbox_command(vha, mcp);
3552 
3553 	/* Return mailbox statuses. */
3554 	if (mb != NULL) {
3555 		mb[0] = mcp->mb[0];
3556 		mb[1] = mcp->mb[1];
3557 		mb[3] = mcp->mb[3];
3558 	}
3559 
3560 	if (rval != QLA_SUCCESS) {
3561 		ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
3562 	} else {
3563 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3564 		    "Done %s.\n", __func__);
3565 		if (port_speed)
3566 			*port_speed = mcp->mb[3];
3567 	}
3568 
3569 	return rval;
3570 }
3571 
3572 int
3573 qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3574     uint16_t port_speed, uint16_t *mb)
3575 {
3576 	int rval;
3577 	mbx_cmd_t mc;
3578 	mbx_cmd_t *mcp = &mc;
3579 
3580 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3581 	    "Entered %s.\n", __func__);
3582 
3583 	if (!IS_IIDMA_CAPABLE(vha->hw))
3584 		return QLA_FUNCTION_FAILED;
3585 
3586 	mcp->mb[0] = MBC_PORT_PARAMS;
3587 	mcp->mb[1] = loop_id;
3588 	mcp->mb[2] = BIT_0;
3589 	if (IS_CNA_CAPABLE(vha->hw))
3590 		mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3591 	else
3592 		mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3593 	mcp->mb[9] = vha->vp_idx;
3594 	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3595 	mcp->in_mb = MBX_3|MBX_1|MBX_0;
3596 	mcp->tov = MBX_TOV_SECONDS;
3597 	mcp->flags = 0;
3598 	rval = qla2x00_mailbox_command(vha, mcp);
3599 
3600 	/* Return mailbox statuses. */
3601 	if (mb != NULL) {
3602 		mb[0] = mcp->mb[0];
3603 		mb[1] = mcp->mb[1];
3604 		mb[3] = mcp->mb[3];
3605 	}
3606 
3607 	if (rval != QLA_SUCCESS) {
3608 		ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3609 		    "Failed=%x.\n", rval);
3610 	} else {
3611 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3612 		    "Done %s.\n", __func__);
3613 	}
3614 
3615 	return rval;
3616 }
3617 
3618 void
3619 qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3620 	struct vp_rpt_id_entry_24xx *rptid_entry)
3621 {
3622 	struct qla_hw_data *ha = vha->hw;
3623 	scsi_qla_host_t *vp = NULL;
3624 	unsigned long   flags;
3625 	int found;
3626 	port_id_t id;
3627 
3628 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3629 	    "Entered %s.\n", __func__);
3630 
3631 	if (rptid_entry->entry_status != 0)
3632 		return;
3633 
3634 	id.b.domain = rptid_entry->port_id[2];
3635 	id.b.area   = rptid_entry->port_id[1];
3636 	id.b.al_pa  = rptid_entry->port_id[0];
3637 	id.b.rsvd_1 = 0;
3638 
3639 	if (rptid_entry->format == 0) {
3640 		/* loop */
3641 		ql_dbg(ql_dbg_async, vha, 0x10b7,
3642 		    "Format 0 : Number of VPs setup %d, number of "
3643 		    "VPs acquired %d.\n", rptid_entry->vp_setup,
3644 		    rptid_entry->vp_acquired);
3645 		ql_dbg(ql_dbg_async, vha, 0x10b8,
3646 		    "Primary port id %02x%02x%02x.\n",
3647 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
3648 		    rptid_entry->port_id[0]);
3649 
3650 		qlt_update_host_map(vha, id);
3651 
3652 	} else if (rptid_entry->format == 1) {
3653 		/* fabric */
3654 		ql_dbg(ql_dbg_async, vha, 0x10b9,
3655 		    "Format 1: VP[%d] enabled - status %d - with "
3656 		    "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
3657 			rptid_entry->vp_status,
3658 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
3659 		    rptid_entry->port_id[0]);
3660 
3661 		/* buffer to buffer credit flag */
3662 		vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
3663 
3664 		if (rptid_entry->vp_idx == 0) {
3665 			if (rptid_entry->vp_status == VP_STAT_COMPL) {
3666 				/* FA-WWN is only for physical port */
3667 				if (qla_ini_mode_enabled(vha) &&
3668 				    ha->flags.fawwpn_enabled &&
3669 				    (rptid_entry->u.f1.flags &
3670 				     VP_FLAGS_NAME_VALID)) {
3671 					memcpy(vha->port_name,
3672 					    rptid_entry->u.f1.port_name,
3673 					    WWN_SIZE);
3674 				}
3675 
3676 				qlt_update_host_map(vha, id);
3677 			}
3678 
3679 			fc_host_port_name(vha->host) =
3680 			    wwn_to_u64(vha->port_name);
3681 
3682 			if (qla_ini_mode_enabled(vha))
3683 				ql_dbg(ql_dbg_mbx, vha, 0x1018,
3684 				    "FA-WWN portname %016llx (%x)\n",
3685 				    fc_host_port_name(vha->host),
3686 				    rptid_entry->vp_status);
3687 
3688 			set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
3689 			set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
3690 		} else {
3691 			if (rptid_entry->vp_status != VP_STAT_COMPL &&
3692 				rptid_entry->vp_status != VP_STAT_ID_CHG) {
3693 				ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3694 				    "Could not acquire ID for VP[%d].\n",
3695 				    rptid_entry->vp_idx);
3696 				return;
3697 			}
3698 
3699 			found = 0;
3700 			spin_lock_irqsave(&ha->vport_slock, flags);
3701 			list_for_each_entry(vp, &ha->vp_list, list) {
3702 				if (rptid_entry->vp_idx == vp->vp_idx) {
3703 					found = 1;
3704 					break;
3705 				}
3706 			}
3707 			spin_unlock_irqrestore(&ha->vport_slock, flags);
3708 
3709 			if (!found)
3710 				return;
3711 
3712 			qlt_update_host_map(vp, id);
3713 
3714 			/*
3715 			 * Cannot configure here as we are still sitting on the
3716 			 * response queue. Handle it in dpc context.
3717 			 */
3718 			set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
3719 			set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3720 			set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3721 		}
3722 		set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
3723 		qla2xxx_wake_dpc(vha);
3724 	} else if (rptid_entry->format == 2) {
3725 		ql_dbg(ql_dbg_async, vha, 0xffff,
3726 		    "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",
3727 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
3728 		    rptid_entry->port_id[0]);
3729 
3730 		ql_dbg(ql_dbg_async, vha, 0xffff,
3731 		    "N2N: Remote WWPN %8phC.\n",
3732 		    rptid_entry->u.f2.port_name);
3733 
3734 		/* N2N.  direct connect */
3735 		vha->d_id.b.domain = rptid_entry->port_id[2];
3736 		vha->d_id.b.area = rptid_entry->port_id[1];
3737 		vha->d_id.b.al_pa = rptid_entry->port_id[0];
3738 
3739 		spin_lock_irqsave(&ha->vport_slock, flags);
3740 		qlt_update_vp_map(vha, SET_AL_PA);
3741 		spin_unlock_irqrestore(&ha->vport_slock, flags);
3742 	}
3743 }
3744 
3745 /*
3746  * qla24xx_modify_vp_config
3747  *	Change VP configuration for vha
3748  *
3749  * Input:
3750  *	vha = adapter block pointer.
3751  *
3752  * Returns:
3753  *	qla2xxx local function return status code.
3754  *
3755  * Context:
3756  *	Kernel context.
3757  */
3758 int
3759 qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3760 {
3761 	int		rval;
3762 	struct vp_config_entry_24xx *vpmod;
3763 	dma_addr_t	vpmod_dma;
3764 	struct qla_hw_data *ha = vha->hw;
3765 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
3766 
3767 	/* This can be called by the parent */
3768 
3769 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3770 	    "Entered %s.\n", __func__);
3771 
3772 	vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
3773 	if (!vpmod) {
3774 		ql_log(ql_log_warn, vha, 0x10bc,
3775 		    "Failed to allocate modify VP IOCB.\n");
3776 		return QLA_MEMORY_ALLOC_FAILED;
3777 	}
3778 
3779 	memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3780 	vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3781 	vpmod->entry_count = 1;
3782 	vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3783 	vpmod->vp_count = 1;
3784 	vpmod->vp_index1 = vha->vp_idx;
3785 	vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
3786 
3787 	qlt_modify_vp_config(vha, vpmod);
3788 
3789 	memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3790 	memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3791 	vpmod->entry_count = 1;
3792 
3793 	rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
3794 	if (rval != QLA_SUCCESS) {
3795 		ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3796 		    "Failed to issue VP config IOCB (%x).\n", rval);
3797 	} else if (vpmod->comp_status != 0) {
3798 		ql_dbg(ql_dbg_mbx, vha, 0x10be,
3799 		    "Failed to complete IOCB -- error status (%x).\n",
3800 		    vpmod->comp_status);
3801 		rval = QLA_FUNCTION_FAILED;
3802 	} else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
3803 		ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3804 		    "Failed to complete IOCB -- completion status (%x).\n",
3805 		    le16_to_cpu(vpmod->comp_status));
3806 		rval = QLA_FUNCTION_FAILED;
3807 	} else {
3808 		/* EMPTY */
3809 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3810 		    "Done %s.\n", __func__);
3811 		fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3812 	}
3813 	dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
3814 
3815 	return rval;
3816 }
3817 
3818 /*
3819  * qla24xx_control_vp
3820  *	Enable a virtual port for given host
3821  *
3822  * Input:
3823  *	ha = adapter block pointer.
3824  *	vhba = virtual adapter (unused)
3825  *	index = index number for enabled VP
3826  *
3827  * Returns:
3828  *	qla2xxx local function return status code.
3829  *
3830  * Context:
3831  *	Kernel context.
3832  */
3833 int
3834 qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3835 {
3836 	int		rval;
3837 	int		map, pos;
3838 	struct vp_ctrl_entry_24xx   *vce;
3839 	dma_addr_t	vce_dma;
3840 	struct qla_hw_data *ha = vha->hw;
3841 	int	vp_index = vha->vp_idx;
3842 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
3843 
3844 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
3845 	    "Entered %s enabling index %d.\n", __func__, vp_index);
3846 
3847 	if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
3848 		return QLA_PARAMETER_ERROR;
3849 
3850 	vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3851 	if (!vce) {
3852 		ql_log(ql_log_warn, vha, 0x10c2,
3853 		    "Failed to allocate VP control IOCB.\n");
3854 		return QLA_MEMORY_ALLOC_FAILED;
3855 	}
3856 	memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3857 
3858 	vce->entry_type = VP_CTRL_IOCB_TYPE;
3859 	vce->entry_count = 1;
3860 	vce->command = cpu_to_le16(cmd);
3861 	vce->vp_count = cpu_to_le16(1);
3862 
3863 	/* index map in firmware starts with 1; decrement index
3864 	 * this is ok as we never use index 0
3865 	 */
3866 	map = (vp_index - 1) / 8;
3867 	pos = (vp_index - 1) & 7;
3868 	mutex_lock(&ha->vport_lock);
3869 	vce->vp_idx_map[map] |= 1 << pos;
3870 	mutex_unlock(&ha->vport_lock);
3871 
3872 	rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
3873 	if (rval != QLA_SUCCESS) {
3874 		ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3875 		    "Failed to issue VP control IOCB (%x).\n", rval);
3876 	} else if (vce->entry_status != 0) {
3877 		ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3878 		    "Failed to complete IOCB -- error status (%x).\n",
3879 		    vce->entry_status);
3880 		rval = QLA_FUNCTION_FAILED;
3881 	} else if (vce->comp_status != cpu_to_le16(CS_COMPLETE)) {
3882 		ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3883 		    "Failed to complet IOCB -- completion status (%x).\n",
3884 		    le16_to_cpu(vce->comp_status));
3885 		rval = QLA_FUNCTION_FAILED;
3886 	} else {
3887 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3888 		    "Done %s.\n", __func__);
3889 	}
3890 
3891 	dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3892 
3893 	return rval;
3894 }
3895 
3896 /*
3897  * qla2x00_send_change_request
3898  *	Receive or disable RSCN request from fabric controller
3899  *
3900  * Input:
3901  *	ha = adapter block pointer
3902  *	format = registration format:
3903  *		0 - Reserved
3904  *		1 - Fabric detected registration
3905  *		2 - N_port detected registration
3906  *		3 - Full registration
3907  *		FF - clear registration
3908  *	vp_idx = Virtual port index
3909  *
3910  * Returns:
3911  *	qla2x00 local function return status code.
3912  *
3913  * Context:
3914  *	Kernel Context
3915  */
3916 
3917 int
3918 qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
3919 			    uint16_t vp_idx)
3920 {
3921 	int rval;
3922 	mbx_cmd_t mc;
3923 	mbx_cmd_t *mcp = &mc;
3924 
3925 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3926 	    "Entered %s.\n", __func__);
3927 
3928 	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3929 	mcp->mb[1] = format;
3930 	mcp->mb[9] = vp_idx;
3931 	mcp->out_mb = MBX_9|MBX_1|MBX_0;
3932 	mcp->in_mb = MBX_0|MBX_1;
3933 	mcp->tov = MBX_TOV_SECONDS;
3934 	mcp->flags = 0;
3935 	rval = qla2x00_mailbox_command(vha, mcp);
3936 
3937 	if (rval == QLA_SUCCESS) {
3938 		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3939 			rval = BIT_1;
3940 		}
3941 	} else
3942 		rval = BIT_1;
3943 
3944 	return rval;
3945 }
3946 
3947 int
3948 qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
3949     uint32_t size)
3950 {
3951 	int rval;
3952 	mbx_cmd_t mc;
3953 	mbx_cmd_t *mcp = &mc;
3954 
3955 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3956 	    "Entered %s.\n", __func__);
3957 
3958 	if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
3959 		mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3960 		mcp->mb[8] = MSW(addr);
3961 		mcp->out_mb = MBX_8|MBX_0;
3962 	} else {
3963 		mcp->mb[0] = MBC_DUMP_RISC_RAM;
3964 		mcp->out_mb = MBX_0;
3965 	}
3966 	mcp->mb[1] = LSW(addr);
3967 	mcp->mb[2] = MSW(req_dma);
3968 	mcp->mb[3] = LSW(req_dma);
3969 	mcp->mb[6] = MSW(MSD(req_dma));
3970 	mcp->mb[7] = LSW(MSD(req_dma));
3971 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
3972 	if (IS_FWI2_CAPABLE(vha->hw)) {
3973 		mcp->mb[4] = MSW(size);
3974 		mcp->mb[5] = LSW(size);
3975 		mcp->out_mb |= MBX_5|MBX_4;
3976 	} else {
3977 		mcp->mb[4] = LSW(size);
3978 		mcp->out_mb |= MBX_4;
3979 	}
3980 
3981 	mcp->in_mb = MBX_0;
3982 	mcp->tov = MBX_TOV_SECONDS;
3983 	mcp->flags = 0;
3984 	rval = qla2x00_mailbox_command(vha, mcp);
3985 
3986 	if (rval != QLA_SUCCESS) {
3987 		ql_dbg(ql_dbg_mbx, vha, 0x1008,
3988 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3989 	} else {
3990 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3991 		    "Done %s.\n", __func__);
3992 	}
3993 
3994 	return rval;
3995 }
3996 /* 84XX Support **************************************************************/
3997 
3998 struct cs84xx_mgmt_cmd {
3999 	union {
4000 		struct verify_chip_entry_84xx req;
4001 		struct verify_chip_rsp_84xx rsp;
4002 	} p;
4003 };
4004 
4005 int
4006 qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
4007 {
4008 	int rval, retry;
4009 	struct cs84xx_mgmt_cmd *mn;
4010 	dma_addr_t mn_dma;
4011 	uint16_t options;
4012 	unsigned long flags;
4013 	struct qla_hw_data *ha = vha->hw;
4014 
4015 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
4016 	    "Entered %s.\n", __func__);
4017 
4018 	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
4019 	if (mn == NULL) {
4020 		return QLA_MEMORY_ALLOC_FAILED;
4021 	}
4022 
4023 	/* Force Update? */
4024 	options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
4025 	/* Diagnostic firmware? */
4026 	/* options |= MENLO_DIAG_FW; */
4027 	/* We update the firmware with only one data sequence. */
4028 	options |= VCO_END_OF_DATA;
4029 
4030 	do {
4031 		retry = 0;
4032 		memset(mn, 0, sizeof(*mn));
4033 		mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
4034 		mn->p.req.entry_count = 1;
4035 		mn->p.req.options = cpu_to_le16(options);
4036 
4037 		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
4038 		    "Dump of Verify Request.\n");
4039 		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
4040 		    (uint8_t *)mn, sizeof(*mn));
4041 
4042 		rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
4043 		if (rval != QLA_SUCCESS) {
4044 			ql_dbg(ql_dbg_mbx, vha, 0x10cb,
4045 			    "Failed to issue verify IOCB (%x).\n", rval);
4046 			goto verify_done;
4047 		}
4048 
4049 		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
4050 		    "Dump of Verify Response.\n");
4051 		ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
4052 		    (uint8_t *)mn, sizeof(*mn));
4053 
4054 		status[0] = le16_to_cpu(mn->p.rsp.comp_status);
4055 		status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
4056 		    le16_to_cpu(mn->p.rsp.failure_code) : 0;
4057 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
4058 		    "cs=%x fc=%x.\n", status[0], status[1]);
4059 
4060 		if (status[0] != CS_COMPLETE) {
4061 			rval = QLA_FUNCTION_FAILED;
4062 			if (!(options & VCO_DONT_UPDATE_FW)) {
4063 				ql_dbg(ql_dbg_mbx, vha, 0x10cf,
4064 				    "Firmware update failed. Retrying "
4065 				    "without update firmware.\n");
4066 				options |= VCO_DONT_UPDATE_FW;
4067 				options &= ~VCO_FORCE_UPDATE;
4068 				retry = 1;
4069 			}
4070 		} else {
4071 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
4072 			    "Firmware updated to %x.\n",
4073 			    le32_to_cpu(mn->p.rsp.fw_ver));
4074 
4075 			/* NOTE: we only update OP firmware. */
4076 			spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
4077 			ha->cs84xx->op_fw_version =
4078 			    le32_to_cpu(mn->p.rsp.fw_ver);
4079 			spin_unlock_irqrestore(&ha->cs84xx->access_lock,
4080 			    flags);
4081 		}
4082 	} while (retry);
4083 
4084 verify_done:
4085 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
4086 
4087 	if (rval != QLA_SUCCESS) {
4088 		ql_dbg(ql_dbg_mbx, vha, 0x10d1,
4089 		    "Failed=%x.\n", rval);
4090 	} else {
4091 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
4092 		    "Done %s.\n", __func__);
4093 	}
4094 
4095 	return rval;
4096 }
4097 
4098 int
4099 qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
4100 {
4101 	int rval;
4102 	unsigned long flags;
4103 	mbx_cmd_t mc;
4104 	mbx_cmd_t *mcp = &mc;
4105 	struct qla_hw_data *ha = vha->hw;
4106 
4107 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
4108 	    "Entered %s.\n", __func__);
4109 
4110 	if (IS_SHADOW_REG_CAPABLE(ha))
4111 		req->options |= BIT_13;
4112 
4113 	mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
4114 	mcp->mb[1] = req->options;
4115 	mcp->mb[2] = MSW(LSD(req->dma));
4116 	mcp->mb[3] = LSW(LSD(req->dma));
4117 	mcp->mb[6] = MSW(MSD(req->dma));
4118 	mcp->mb[7] = LSW(MSD(req->dma));
4119 	mcp->mb[5] = req->length;
4120 	if (req->rsp)
4121 		mcp->mb[10] = req->rsp->id;
4122 	mcp->mb[12] = req->qos;
4123 	mcp->mb[11] = req->vp_idx;
4124 	mcp->mb[13] = req->rid;
4125 	if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
4126 		mcp->mb[15] = 0;
4127 
4128 	mcp->mb[4] = req->id;
4129 	/* que in ptr index */
4130 	mcp->mb[8] = 0;
4131 	/* que out ptr index */
4132 	mcp->mb[9] = *req->out_ptr = 0;
4133 	mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
4134 			MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4135 	mcp->in_mb = MBX_0;
4136 	mcp->flags = MBX_DMA_OUT;
4137 	mcp->tov = MBX_TOV_SECONDS * 2;
4138 
4139 	if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
4140 		mcp->in_mb |= MBX_1;
4141 	if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4142 		mcp->out_mb |= MBX_15;
4143 		/* debug q create issue in SR-IOV */
4144 		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4145 	}
4146 
4147 	spin_lock_irqsave(&ha->hardware_lock, flags);
4148 	if (!(req->options & BIT_0)) {
4149 		WRT_REG_DWORD(req->req_q_in, 0);
4150 		if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
4151 			WRT_REG_DWORD(req->req_q_out, 0);
4152 	}
4153 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
4154 
4155 	rval = qla2x00_mailbox_command(vha, mcp);
4156 	if (rval != QLA_SUCCESS) {
4157 		ql_dbg(ql_dbg_mbx, vha, 0x10d4,
4158 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4159 	} else {
4160 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
4161 		    "Done %s.\n", __func__);
4162 	}
4163 
4164 	return rval;
4165 }
4166 
4167 int
4168 qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
4169 {
4170 	int rval;
4171 	unsigned long flags;
4172 	mbx_cmd_t mc;
4173 	mbx_cmd_t *mcp = &mc;
4174 	struct qla_hw_data *ha = vha->hw;
4175 
4176 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
4177 	    "Entered %s.\n", __func__);
4178 
4179 	if (IS_SHADOW_REG_CAPABLE(ha))
4180 		rsp->options |= BIT_13;
4181 
4182 	mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
4183 	mcp->mb[1] = rsp->options;
4184 	mcp->mb[2] = MSW(LSD(rsp->dma));
4185 	mcp->mb[3] = LSW(LSD(rsp->dma));
4186 	mcp->mb[6] = MSW(MSD(rsp->dma));
4187 	mcp->mb[7] = LSW(MSD(rsp->dma));
4188 	mcp->mb[5] = rsp->length;
4189 	mcp->mb[14] = rsp->msix->entry;
4190 	mcp->mb[13] = rsp->rid;
4191 	if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
4192 		mcp->mb[15] = 0;
4193 
4194 	mcp->mb[4] = rsp->id;
4195 	/* que in ptr index */
4196 	mcp->mb[8] = *rsp->in_ptr = 0;
4197 	/* que out ptr index */
4198 	mcp->mb[9] = 0;
4199 	mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
4200 			|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4201 	mcp->in_mb = MBX_0;
4202 	mcp->flags = MBX_DMA_OUT;
4203 	mcp->tov = MBX_TOV_SECONDS * 2;
4204 
4205 	if (IS_QLA81XX(ha)) {
4206 		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
4207 		mcp->in_mb |= MBX_1;
4208 	} else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4209 		mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
4210 		mcp->in_mb |= MBX_1;
4211 		/* debug q create issue in SR-IOV */
4212 		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4213 	}
4214 
4215 	spin_lock_irqsave(&ha->hardware_lock, flags);
4216 	if (!(rsp->options & BIT_0)) {
4217 		WRT_REG_DWORD(rsp->rsp_q_out, 0);
4218 		if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
4219 			WRT_REG_DWORD(rsp->rsp_q_in, 0);
4220 	}
4221 
4222 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
4223 
4224 	rval = qla2x00_mailbox_command(vha, mcp);
4225 	if (rval != QLA_SUCCESS) {
4226 		ql_dbg(ql_dbg_mbx, vha, 0x10d7,
4227 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4228 	} else {
4229 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
4230 		    "Done %s.\n", __func__);
4231 	}
4232 
4233 	return rval;
4234 }
4235 
4236 int
4237 qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
4238 {
4239 	int rval;
4240 	mbx_cmd_t mc;
4241 	mbx_cmd_t *mcp = &mc;
4242 
4243 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
4244 	    "Entered %s.\n", __func__);
4245 
4246 	mcp->mb[0] = MBC_IDC_ACK;
4247 	memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
4248 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4249 	mcp->in_mb = MBX_0;
4250 	mcp->tov = MBX_TOV_SECONDS;
4251 	mcp->flags = 0;
4252 	rval = qla2x00_mailbox_command(vha, mcp);
4253 
4254 	if (rval != QLA_SUCCESS) {
4255 		ql_dbg(ql_dbg_mbx, vha, 0x10da,
4256 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4257 	} else {
4258 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
4259 		    "Done %s.\n", __func__);
4260 	}
4261 
4262 	return rval;
4263 }
4264 
4265 int
4266 qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
4267 {
4268 	int rval;
4269 	mbx_cmd_t mc;
4270 	mbx_cmd_t *mcp = &mc;
4271 
4272 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
4273 	    "Entered %s.\n", __func__);
4274 
4275 	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4276 	    !IS_QLA27XX(vha->hw))
4277 		return QLA_FUNCTION_FAILED;
4278 
4279 	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4280 	mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
4281 	mcp->out_mb = MBX_1|MBX_0;
4282 	mcp->in_mb = MBX_1|MBX_0;
4283 	mcp->tov = MBX_TOV_SECONDS;
4284 	mcp->flags = 0;
4285 	rval = qla2x00_mailbox_command(vha, mcp);
4286 
4287 	if (rval != QLA_SUCCESS) {
4288 		ql_dbg(ql_dbg_mbx, vha, 0x10dd,
4289 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
4290 		    rval, mcp->mb[0], mcp->mb[1]);
4291 	} else {
4292 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
4293 		    "Done %s.\n", __func__);
4294 		*sector_size = mcp->mb[1];
4295 	}
4296 
4297 	return rval;
4298 }
4299 
4300 int
4301 qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
4302 {
4303 	int rval;
4304 	mbx_cmd_t mc;
4305 	mbx_cmd_t *mcp = &mc;
4306 
4307 	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4308 	    !IS_QLA27XX(vha->hw))
4309 		return QLA_FUNCTION_FAILED;
4310 
4311 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
4312 	    "Entered %s.\n", __func__);
4313 
4314 	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4315 	mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
4316 	    FAC_OPT_CMD_WRITE_PROTECT;
4317 	mcp->out_mb = MBX_1|MBX_0;
4318 	mcp->in_mb = MBX_1|MBX_0;
4319 	mcp->tov = MBX_TOV_SECONDS;
4320 	mcp->flags = 0;
4321 	rval = qla2x00_mailbox_command(vha, mcp);
4322 
4323 	if (rval != QLA_SUCCESS) {
4324 		ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4325 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
4326 		    rval, mcp->mb[0], mcp->mb[1]);
4327 	} else {
4328 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4329 		    "Done %s.\n", __func__);
4330 	}
4331 
4332 	return rval;
4333 }
4334 
4335 int
4336 qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4337 {
4338 	int rval;
4339 	mbx_cmd_t mc;
4340 	mbx_cmd_t *mcp = &mc;
4341 
4342 	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4343 	    !IS_QLA27XX(vha->hw))
4344 		return QLA_FUNCTION_FAILED;
4345 
4346 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4347 	    "Entered %s.\n", __func__);
4348 
4349 	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4350 	mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4351 	mcp->mb[2] = LSW(start);
4352 	mcp->mb[3] = MSW(start);
4353 	mcp->mb[4] = LSW(finish);
4354 	mcp->mb[5] = MSW(finish);
4355 	mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4356 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
4357 	mcp->tov = MBX_TOV_SECONDS;
4358 	mcp->flags = 0;
4359 	rval = qla2x00_mailbox_command(vha, mcp);
4360 
4361 	if (rval != QLA_SUCCESS) {
4362 		ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4363 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4364 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
4365 	} else {
4366 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4367 		    "Done %s.\n", __func__);
4368 	}
4369 
4370 	return rval;
4371 }
4372 
4373 int
4374 qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4375 {
4376 	int rval = 0;
4377 	mbx_cmd_t mc;
4378 	mbx_cmd_t *mcp = &mc;
4379 
4380 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4381 	    "Entered %s.\n", __func__);
4382 
4383 	mcp->mb[0] = MBC_RESTART_MPI_FW;
4384 	mcp->out_mb = MBX_0;
4385 	mcp->in_mb = MBX_0|MBX_1;
4386 	mcp->tov = MBX_TOV_SECONDS;
4387 	mcp->flags = 0;
4388 	rval = qla2x00_mailbox_command(vha, mcp);
4389 
4390 	if (rval != QLA_SUCCESS) {
4391 		ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4392 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
4393 		    rval, mcp->mb[0], mcp->mb[1]);
4394 	} else {
4395 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4396 		    "Done %s.\n", __func__);
4397 	}
4398 
4399 	return rval;
4400 }
4401 
4402 int
4403 qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4404 {
4405 	int rval;
4406 	mbx_cmd_t mc;
4407 	mbx_cmd_t *mcp = &mc;
4408 	int i;
4409 	int len;
4410 	uint16_t *str;
4411 	struct qla_hw_data *ha = vha->hw;
4412 
4413 	if (!IS_P3P_TYPE(ha))
4414 		return QLA_FUNCTION_FAILED;
4415 
4416 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4417 	    "Entered %s.\n", __func__);
4418 
4419 	str = (void *)version;
4420 	len = strlen(version);
4421 
4422 	mcp->mb[0] = MBC_SET_RNID_PARAMS;
4423 	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4424 	mcp->out_mb = MBX_1|MBX_0;
4425 	for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4426 		mcp->mb[i] = cpu_to_le16p(str);
4427 		mcp->out_mb |= 1<<i;
4428 	}
4429 	for (; i < 16; i++) {
4430 		mcp->mb[i] = 0;
4431 		mcp->out_mb |= 1<<i;
4432 	}
4433 	mcp->in_mb = MBX_1|MBX_0;
4434 	mcp->tov = MBX_TOV_SECONDS;
4435 	mcp->flags = 0;
4436 	rval = qla2x00_mailbox_command(vha, mcp);
4437 
4438 	if (rval != QLA_SUCCESS) {
4439 		ql_dbg(ql_dbg_mbx, vha, 0x117c,
4440 		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4441 	} else {
4442 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4443 		    "Done %s.\n", __func__);
4444 	}
4445 
4446 	return rval;
4447 }
4448 
4449 int
4450 qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4451 {
4452 	int rval;
4453 	mbx_cmd_t mc;
4454 	mbx_cmd_t *mcp = &mc;
4455 	int len;
4456 	uint16_t dwlen;
4457 	uint8_t *str;
4458 	dma_addr_t str_dma;
4459 	struct qla_hw_data *ha = vha->hw;
4460 
4461 	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4462 	    IS_P3P_TYPE(ha))
4463 		return QLA_FUNCTION_FAILED;
4464 
4465 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4466 	    "Entered %s.\n", __func__);
4467 
4468 	str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4469 	if (!str) {
4470 		ql_log(ql_log_warn, vha, 0x117f,
4471 		    "Failed to allocate driver version param.\n");
4472 		return QLA_MEMORY_ALLOC_FAILED;
4473 	}
4474 
4475 	memcpy(str, "\x7\x3\x11\x0", 4);
4476 	dwlen = str[0];
4477 	len = dwlen * 4 - 4;
4478 	memset(str + 4, 0, len);
4479 	if (len > strlen(version))
4480 		len = strlen(version);
4481 	memcpy(str + 4, version, len);
4482 
4483 	mcp->mb[0] = MBC_SET_RNID_PARAMS;
4484 	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4485 	mcp->mb[2] = MSW(LSD(str_dma));
4486 	mcp->mb[3] = LSW(LSD(str_dma));
4487 	mcp->mb[6] = MSW(MSD(str_dma));
4488 	mcp->mb[7] = LSW(MSD(str_dma));
4489 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4490 	mcp->in_mb = MBX_1|MBX_0;
4491 	mcp->tov = MBX_TOV_SECONDS;
4492 	mcp->flags = 0;
4493 	rval = qla2x00_mailbox_command(vha, mcp);
4494 
4495 	if (rval != QLA_SUCCESS) {
4496 		ql_dbg(ql_dbg_mbx, vha, 0x1180,
4497 		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4498 	} else {
4499 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4500 		    "Done %s.\n", __func__);
4501 	}
4502 
4503 	dma_pool_free(ha->s_dma_pool, str, str_dma);
4504 
4505 	return rval;
4506 }
4507 
4508 static int
4509 qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4510 {
4511 	int rval;
4512 	mbx_cmd_t mc;
4513 	mbx_cmd_t *mcp = &mc;
4514 
4515 	if (!IS_FWI2_CAPABLE(vha->hw))
4516 		return QLA_FUNCTION_FAILED;
4517 
4518 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4519 	    "Entered %s.\n", __func__);
4520 
4521 	mcp->mb[0] = MBC_GET_RNID_PARAMS;
4522 	mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4523 	mcp->out_mb = MBX_1|MBX_0;
4524 	mcp->in_mb = MBX_1|MBX_0;
4525 	mcp->tov = MBX_TOV_SECONDS;
4526 	mcp->flags = 0;
4527 	rval = qla2x00_mailbox_command(vha, mcp);
4528 	*temp = mcp->mb[1];
4529 
4530 	if (rval != QLA_SUCCESS) {
4531 		ql_dbg(ql_dbg_mbx, vha, 0x115a,
4532 		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4533 	} else {
4534 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4535 		    "Done %s.\n", __func__);
4536 	}
4537 
4538 	return rval;
4539 }
4540 
4541 int
4542 qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4543 	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
4544 {
4545 	int rval;
4546 	mbx_cmd_t mc;
4547 	mbx_cmd_t *mcp = &mc;
4548 	struct qla_hw_data *ha = vha->hw;
4549 
4550 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4551 	    "Entered %s.\n", __func__);
4552 
4553 	if (!IS_FWI2_CAPABLE(ha))
4554 		return QLA_FUNCTION_FAILED;
4555 
4556 	if (len == 1)
4557 		opt |= BIT_0;
4558 
4559 	mcp->mb[0] = MBC_READ_SFP;
4560 	mcp->mb[1] = dev;
4561 	mcp->mb[2] = MSW(sfp_dma);
4562 	mcp->mb[3] = LSW(sfp_dma);
4563 	mcp->mb[6] = MSW(MSD(sfp_dma));
4564 	mcp->mb[7] = LSW(MSD(sfp_dma));
4565 	mcp->mb[8] = len;
4566 	mcp->mb[9] = off;
4567 	mcp->mb[10] = opt;
4568 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4569 	mcp->in_mb = MBX_1|MBX_0;
4570 	mcp->tov = MBX_TOV_SECONDS;
4571 	mcp->flags = 0;
4572 	rval = qla2x00_mailbox_command(vha, mcp);
4573 
4574 	if (opt & BIT_0)
4575 		*sfp = mcp->mb[1];
4576 
4577 	if (rval != QLA_SUCCESS) {
4578 		ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4579 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4580 	} else {
4581 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4582 		    "Done %s.\n", __func__);
4583 	}
4584 
4585 	return rval;
4586 }
4587 
4588 int
4589 qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4590 	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
4591 {
4592 	int rval;
4593 	mbx_cmd_t mc;
4594 	mbx_cmd_t *mcp = &mc;
4595 	struct qla_hw_data *ha = vha->hw;
4596 
4597 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4598 	    "Entered %s.\n", __func__);
4599 
4600 	if (!IS_FWI2_CAPABLE(ha))
4601 		return QLA_FUNCTION_FAILED;
4602 
4603 	if (len == 1)
4604 		opt |= BIT_0;
4605 
4606 	if (opt & BIT_0)
4607 		len = *sfp;
4608 
4609 	mcp->mb[0] = MBC_WRITE_SFP;
4610 	mcp->mb[1] = dev;
4611 	mcp->mb[2] = MSW(sfp_dma);
4612 	mcp->mb[3] = LSW(sfp_dma);
4613 	mcp->mb[6] = MSW(MSD(sfp_dma));
4614 	mcp->mb[7] = LSW(MSD(sfp_dma));
4615 	mcp->mb[8] = len;
4616 	mcp->mb[9] = off;
4617 	mcp->mb[10] = opt;
4618 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4619 	mcp->in_mb = MBX_1|MBX_0;
4620 	mcp->tov = MBX_TOV_SECONDS;
4621 	mcp->flags = 0;
4622 	rval = qla2x00_mailbox_command(vha, mcp);
4623 
4624 	if (rval != QLA_SUCCESS) {
4625 		ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4626 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4627 	} else {
4628 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4629 		    "Done %s.\n", __func__);
4630 	}
4631 
4632 	return rval;
4633 }
4634 
4635 int
4636 qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4637     uint16_t size_in_bytes, uint16_t *actual_size)
4638 {
4639 	int rval;
4640 	mbx_cmd_t mc;
4641 	mbx_cmd_t *mcp = &mc;
4642 
4643 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4644 	    "Entered %s.\n", __func__);
4645 
4646 	if (!IS_CNA_CAPABLE(vha->hw))
4647 		return QLA_FUNCTION_FAILED;
4648 
4649 	mcp->mb[0] = MBC_GET_XGMAC_STATS;
4650 	mcp->mb[2] = MSW(stats_dma);
4651 	mcp->mb[3] = LSW(stats_dma);
4652 	mcp->mb[6] = MSW(MSD(stats_dma));
4653 	mcp->mb[7] = LSW(MSD(stats_dma));
4654 	mcp->mb[8] = size_in_bytes >> 2;
4655 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4656 	mcp->in_mb = MBX_2|MBX_1|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, 0x10ef,
4663 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4664 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
4665 	} else {
4666 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4667 		    "Done %s.\n", __func__);
4668 
4669 
4670 		*actual_size = mcp->mb[2] << 2;
4671 	}
4672 
4673 	return rval;
4674 }
4675 
4676 int
4677 qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4678     uint16_t size)
4679 {
4680 	int rval;
4681 	mbx_cmd_t mc;
4682 	mbx_cmd_t *mcp = &mc;
4683 
4684 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4685 	    "Entered %s.\n", __func__);
4686 
4687 	if (!IS_CNA_CAPABLE(vha->hw))
4688 		return QLA_FUNCTION_FAILED;
4689 
4690 	mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4691 	mcp->mb[1] = 0;
4692 	mcp->mb[2] = MSW(tlv_dma);
4693 	mcp->mb[3] = LSW(tlv_dma);
4694 	mcp->mb[6] = MSW(MSD(tlv_dma));
4695 	mcp->mb[7] = LSW(MSD(tlv_dma));
4696 	mcp->mb[8] = size;
4697 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4698 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
4699 	mcp->tov = MBX_TOV_SECONDS;
4700 	mcp->flags = 0;
4701 	rval = qla2x00_mailbox_command(vha, mcp);
4702 
4703 	if (rval != QLA_SUCCESS) {
4704 		ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4705 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4706 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
4707 	} else {
4708 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4709 		    "Done %s.\n", __func__);
4710 	}
4711 
4712 	return rval;
4713 }
4714 
4715 int
4716 qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4717 {
4718 	int rval;
4719 	mbx_cmd_t mc;
4720 	mbx_cmd_t *mcp = &mc;
4721 
4722 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4723 	    "Entered %s.\n", __func__);
4724 
4725 	if (!IS_FWI2_CAPABLE(vha->hw))
4726 		return QLA_FUNCTION_FAILED;
4727 
4728 	mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4729 	mcp->mb[1] = LSW(risc_addr);
4730 	mcp->mb[8] = MSW(risc_addr);
4731 	mcp->out_mb = MBX_8|MBX_1|MBX_0;
4732 	mcp->in_mb = MBX_3|MBX_2|MBX_0;
4733 	mcp->tov = 30;
4734 	mcp->flags = 0;
4735 	rval = qla2x00_mailbox_command(vha, mcp);
4736 	if (rval != QLA_SUCCESS) {
4737 		ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4738 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4739 	} else {
4740 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4741 		    "Done %s.\n", __func__);
4742 		*data = mcp->mb[3] << 16 | mcp->mb[2];
4743 	}
4744 
4745 	return rval;
4746 }
4747 
4748 int
4749 qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4750 	uint16_t *mresp)
4751 {
4752 	int rval;
4753 	mbx_cmd_t mc;
4754 	mbx_cmd_t *mcp = &mc;
4755 
4756 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4757 	    "Entered %s.\n", __func__);
4758 
4759 	memset(mcp->mb, 0 , sizeof(mcp->mb));
4760 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4761 	mcp->mb[1] = mreq->options | BIT_6;	// BIT_6 specifies 64 bit addressing
4762 
4763 	/* transfer count */
4764 	mcp->mb[10] = LSW(mreq->transfer_size);
4765 	mcp->mb[11] = MSW(mreq->transfer_size);
4766 
4767 	/* send data address */
4768 	mcp->mb[14] = LSW(mreq->send_dma);
4769 	mcp->mb[15] = MSW(mreq->send_dma);
4770 	mcp->mb[20] = LSW(MSD(mreq->send_dma));
4771 	mcp->mb[21] = MSW(MSD(mreq->send_dma));
4772 
4773 	/* receive data address */
4774 	mcp->mb[16] = LSW(mreq->rcv_dma);
4775 	mcp->mb[17] = MSW(mreq->rcv_dma);
4776 	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4777 	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4778 
4779 	/* Iteration count */
4780 	mcp->mb[18] = LSW(mreq->iteration_count);
4781 	mcp->mb[19] = MSW(mreq->iteration_count);
4782 
4783 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4784 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
4785 	if (IS_CNA_CAPABLE(vha->hw))
4786 		mcp->out_mb |= MBX_2;
4787 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4788 
4789 	mcp->buf_size = mreq->transfer_size;
4790 	mcp->tov = MBX_TOV_SECONDS;
4791 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4792 
4793 	rval = qla2x00_mailbox_command(vha, mcp);
4794 
4795 	if (rval != QLA_SUCCESS) {
4796 		ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4797 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4798 		    "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4799 		    mcp->mb[3], mcp->mb[18], mcp->mb[19]);
4800 	} else {
4801 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4802 		    "Done %s.\n", __func__);
4803 	}
4804 
4805 	/* Copy mailbox information */
4806 	memcpy( mresp, mcp->mb, 64);
4807 	return rval;
4808 }
4809 
4810 int
4811 qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4812 	uint16_t *mresp)
4813 {
4814 	int rval;
4815 	mbx_cmd_t mc;
4816 	mbx_cmd_t *mcp = &mc;
4817 	struct qla_hw_data *ha = vha->hw;
4818 
4819 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4820 	    "Entered %s.\n", __func__);
4821 
4822 	memset(mcp->mb, 0 , sizeof(mcp->mb));
4823 	mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4824 	mcp->mb[1] = mreq->options | BIT_6;	/* BIT_6 specifies 64bit address */
4825 	if (IS_CNA_CAPABLE(ha)) {
4826 		mcp->mb[1] |= BIT_15;
4827 		mcp->mb[2] = vha->fcoe_fcf_idx;
4828 	}
4829 	mcp->mb[16] = LSW(mreq->rcv_dma);
4830 	mcp->mb[17] = MSW(mreq->rcv_dma);
4831 	mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4832 	mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4833 
4834 	mcp->mb[10] = LSW(mreq->transfer_size);
4835 
4836 	mcp->mb[14] = LSW(mreq->send_dma);
4837 	mcp->mb[15] = MSW(mreq->send_dma);
4838 	mcp->mb[20] = LSW(MSD(mreq->send_dma));
4839 	mcp->mb[21] = MSW(MSD(mreq->send_dma));
4840 
4841 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4842 	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
4843 	if (IS_CNA_CAPABLE(ha))
4844 		mcp->out_mb |= MBX_2;
4845 
4846 	mcp->in_mb = MBX_0;
4847 	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4848 	    IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
4849 		mcp->in_mb |= MBX_1;
4850 	if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
4851 		mcp->in_mb |= MBX_3;
4852 
4853 	mcp->tov = MBX_TOV_SECONDS;
4854 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4855 	mcp->buf_size = mreq->transfer_size;
4856 
4857 	rval = qla2x00_mailbox_command(vha, mcp);
4858 
4859 	if (rval != QLA_SUCCESS) {
4860 		ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4861 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
4862 		    rval, mcp->mb[0], mcp->mb[1]);
4863 	} else {
4864 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4865 		    "Done %s.\n", __func__);
4866 	}
4867 
4868 	/* Copy mailbox information */
4869 	memcpy(mresp, mcp->mb, 64);
4870 	return rval;
4871 }
4872 
4873 int
4874 qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
4875 {
4876 	int rval;
4877 	mbx_cmd_t mc;
4878 	mbx_cmd_t *mcp = &mc;
4879 
4880 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
4881 	    "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
4882 
4883 	mcp->mb[0] = MBC_ISP84XX_RESET;
4884 	mcp->mb[1] = enable_diagnostic;
4885 	mcp->out_mb = MBX_1|MBX_0;
4886 	mcp->in_mb = MBX_1|MBX_0;
4887 	mcp->tov = MBX_TOV_SECONDS;
4888 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4889 	rval = qla2x00_mailbox_command(vha, mcp);
4890 
4891 	if (rval != QLA_SUCCESS)
4892 		ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
4893 	else
4894 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4895 		    "Done %s.\n", __func__);
4896 
4897 	return rval;
4898 }
4899 
4900 int
4901 qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4902 {
4903 	int rval;
4904 	mbx_cmd_t mc;
4905 	mbx_cmd_t *mcp = &mc;
4906 
4907 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4908 	    "Entered %s.\n", __func__);
4909 
4910 	if (!IS_FWI2_CAPABLE(vha->hw))
4911 		return QLA_FUNCTION_FAILED;
4912 
4913 	mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4914 	mcp->mb[1] = LSW(risc_addr);
4915 	mcp->mb[2] = LSW(data);
4916 	mcp->mb[3] = MSW(data);
4917 	mcp->mb[8] = MSW(risc_addr);
4918 	mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4919 	mcp->in_mb = MBX_0;
4920 	mcp->tov = 30;
4921 	mcp->flags = 0;
4922 	rval = qla2x00_mailbox_command(vha, mcp);
4923 	if (rval != QLA_SUCCESS) {
4924 		ql_dbg(ql_dbg_mbx, vha, 0x1101,
4925 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4926 	} else {
4927 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4928 		    "Done %s.\n", __func__);
4929 	}
4930 
4931 	return rval;
4932 }
4933 
4934 int
4935 qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4936 {
4937 	int rval;
4938 	uint32_t stat, timer;
4939 	uint16_t mb0 = 0;
4940 	struct qla_hw_data *ha = vha->hw;
4941 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4942 
4943 	rval = QLA_SUCCESS;
4944 
4945 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4946 	    "Entered %s.\n", __func__);
4947 
4948 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4949 
4950 	/* Write the MBC data to the registers */
4951 	WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4952 	WRT_REG_WORD(&reg->mailbox1, mb[0]);
4953 	WRT_REG_WORD(&reg->mailbox2, mb[1]);
4954 	WRT_REG_WORD(&reg->mailbox3, mb[2]);
4955 	WRT_REG_WORD(&reg->mailbox4, mb[3]);
4956 
4957 	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4958 
4959 	/* Poll for MBC interrupt */
4960 	for (timer = 6000000; timer; timer--) {
4961 		/* Check for pending interrupts. */
4962 		stat = RD_REG_DWORD(&reg->host_status);
4963 		if (stat & HSRX_RISC_INT) {
4964 			stat &= 0xff;
4965 
4966 			if (stat == 0x1 || stat == 0x2 ||
4967 			    stat == 0x10 || stat == 0x11) {
4968 				set_bit(MBX_INTERRUPT,
4969 				    &ha->mbx_cmd_flags);
4970 				mb0 = RD_REG_WORD(&reg->mailbox0);
4971 				WRT_REG_DWORD(&reg->hccr,
4972 				    HCCRX_CLR_RISC_INT);
4973 				RD_REG_DWORD(&reg->hccr);
4974 				break;
4975 			}
4976 		}
4977 		udelay(5);
4978 	}
4979 
4980 	if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4981 		rval = mb0 & MBS_MASK;
4982 	else
4983 		rval = QLA_FUNCTION_FAILED;
4984 
4985 	if (rval != QLA_SUCCESS) {
4986 		ql_dbg(ql_dbg_mbx, vha, 0x1104,
4987 		    "Failed=%x mb[0]=%x.\n", rval, mb[0]);
4988 	} else {
4989 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4990 		    "Done %s.\n", __func__);
4991 	}
4992 
4993 	return rval;
4994 }
4995 
4996 int
4997 qla2x00_get_data_rate(scsi_qla_host_t *vha)
4998 {
4999 	int rval;
5000 	mbx_cmd_t mc;
5001 	mbx_cmd_t *mcp = &mc;
5002 	struct qla_hw_data *ha = vha->hw;
5003 
5004 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
5005 	    "Entered %s.\n", __func__);
5006 
5007 	if (!IS_FWI2_CAPABLE(ha))
5008 		return QLA_FUNCTION_FAILED;
5009 
5010 	mcp->mb[0] = MBC_DATA_RATE;
5011 	mcp->mb[1] = 0;
5012 	mcp->out_mb = MBX_1|MBX_0;
5013 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
5014 	if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
5015 		mcp->in_mb |= MBX_3;
5016 	mcp->tov = MBX_TOV_SECONDS;
5017 	mcp->flags = 0;
5018 	rval = qla2x00_mailbox_command(vha, mcp);
5019 	if (rval != QLA_SUCCESS) {
5020 		ql_dbg(ql_dbg_mbx, vha, 0x1107,
5021 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5022 	} else {
5023 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
5024 		    "Done %s.\n", __func__);
5025 		if (mcp->mb[1] != 0x7)
5026 			ha->link_data_rate = mcp->mb[1];
5027 	}
5028 
5029 	return rval;
5030 }
5031 
5032 int
5033 qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5034 {
5035 	int rval;
5036 	mbx_cmd_t mc;
5037 	mbx_cmd_t *mcp = &mc;
5038 	struct qla_hw_data *ha = vha->hw;
5039 
5040 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
5041 	    "Entered %s.\n", __func__);
5042 
5043 	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
5044 	    !IS_QLA27XX(ha))
5045 		return QLA_FUNCTION_FAILED;
5046 	mcp->mb[0] = MBC_GET_PORT_CONFIG;
5047 	mcp->out_mb = MBX_0;
5048 	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5049 	mcp->tov = MBX_TOV_SECONDS;
5050 	mcp->flags = 0;
5051 
5052 	rval = qla2x00_mailbox_command(vha, mcp);
5053 
5054 	if (rval != QLA_SUCCESS) {
5055 		ql_dbg(ql_dbg_mbx, vha, 0x110a,
5056 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5057 	} else {
5058 		/* Copy all bits to preserve original value */
5059 		memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
5060 
5061 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
5062 		    "Done %s.\n", __func__);
5063 	}
5064 	return rval;
5065 }
5066 
5067 int
5068 qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5069 {
5070 	int rval;
5071 	mbx_cmd_t mc;
5072 	mbx_cmd_t *mcp = &mc;
5073 
5074 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
5075 	    "Entered %s.\n", __func__);
5076 
5077 	mcp->mb[0] = MBC_SET_PORT_CONFIG;
5078 	/* Copy all bits to preserve original setting */
5079 	memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
5080 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5081 	mcp->in_mb = MBX_0;
5082 	mcp->tov = MBX_TOV_SECONDS;
5083 	mcp->flags = 0;
5084 	rval = qla2x00_mailbox_command(vha, mcp);
5085 
5086 	if (rval != QLA_SUCCESS) {
5087 		ql_dbg(ql_dbg_mbx, vha, 0x110d,
5088 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5089 	} else
5090 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
5091 		    "Done %s.\n", __func__);
5092 
5093 	return rval;
5094 }
5095 
5096 
5097 int
5098 qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
5099 		uint16_t *mb)
5100 {
5101 	int rval;
5102 	mbx_cmd_t mc;
5103 	mbx_cmd_t *mcp = &mc;
5104 	struct qla_hw_data *ha = vha->hw;
5105 
5106 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
5107 	    "Entered %s.\n", __func__);
5108 
5109 	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
5110 		return QLA_FUNCTION_FAILED;
5111 
5112 	mcp->mb[0] = MBC_PORT_PARAMS;
5113 	mcp->mb[1] = loop_id;
5114 	if (ha->flags.fcp_prio_enabled)
5115 		mcp->mb[2] = BIT_1;
5116 	else
5117 		mcp->mb[2] = BIT_2;
5118 	mcp->mb[4] = priority & 0xf;
5119 	mcp->mb[9] = vha->vp_idx;
5120 	mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5121 	mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5122 	mcp->tov = 30;
5123 	mcp->flags = 0;
5124 	rval = qla2x00_mailbox_command(vha, mcp);
5125 	if (mb != NULL) {
5126 		mb[0] = mcp->mb[0];
5127 		mb[1] = mcp->mb[1];
5128 		mb[3] = mcp->mb[3];
5129 		mb[4] = mcp->mb[4];
5130 	}
5131 
5132 	if (rval != QLA_SUCCESS) {
5133 		ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
5134 	} else {
5135 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
5136 		    "Done %s.\n", __func__);
5137 	}
5138 
5139 	return rval;
5140 }
5141 
5142 int
5143 qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
5144 {
5145 	int rval = QLA_FUNCTION_FAILED;
5146 	struct qla_hw_data *ha = vha->hw;
5147 	uint8_t byte;
5148 
5149 	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
5150 		ql_dbg(ql_dbg_mbx, vha, 0x1150,
5151 		    "Thermal not supported by this card.\n");
5152 		return rval;
5153 	}
5154 
5155 	if (IS_QLA25XX(ha)) {
5156 		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
5157 		    ha->pdev->subsystem_device == 0x0175) {
5158 			rval = qla2x00_read_sfp(vha, 0, &byte,
5159 			    0x98, 0x1, 1, BIT_13|BIT_0);
5160 			*temp = byte;
5161 			return rval;
5162 		}
5163 		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
5164 		    ha->pdev->subsystem_device == 0x338e) {
5165 			rval = qla2x00_read_sfp(vha, 0, &byte,
5166 			    0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
5167 			*temp = byte;
5168 			return rval;
5169 		}
5170 		ql_dbg(ql_dbg_mbx, vha, 0x10c9,
5171 		    "Thermal not supported by this card.\n");
5172 		return rval;
5173 	}
5174 
5175 	if (IS_QLA82XX(ha)) {
5176 		*temp = qla82xx_read_temperature(vha);
5177 		rval = QLA_SUCCESS;
5178 		return rval;
5179 	} else if (IS_QLA8044(ha)) {
5180 		*temp = qla8044_read_temperature(vha);
5181 		rval = QLA_SUCCESS;
5182 		return rval;
5183 	}
5184 
5185 	rval = qla2x00_read_asic_temperature(vha, temp);
5186 	return rval;
5187 }
5188 
5189 int
5190 qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5191 {
5192 	int rval;
5193 	struct qla_hw_data *ha = vha->hw;
5194 	mbx_cmd_t mc;
5195 	mbx_cmd_t *mcp = &mc;
5196 
5197 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
5198 	    "Entered %s.\n", __func__);
5199 
5200 	if (!IS_FWI2_CAPABLE(ha))
5201 		return QLA_FUNCTION_FAILED;
5202 
5203 	memset(mcp, 0, sizeof(mbx_cmd_t));
5204 	mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5205 	mcp->mb[1] = 1;
5206 
5207 	mcp->out_mb = MBX_1|MBX_0;
5208 	mcp->in_mb = MBX_0;
5209 	mcp->tov = 30;
5210 	mcp->flags = 0;
5211 
5212 	rval = qla2x00_mailbox_command(vha, mcp);
5213 	if (rval != QLA_SUCCESS) {
5214 		ql_dbg(ql_dbg_mbx, vha, 0x1016,
5215 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5216 	} else {
5217 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
5218 		    "Done %s.\n", __func__);
5219 	}
5220 
5221 	return rval;
5222 }
5223 
5224 int
5225 qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5226 {
5227 	int rval;
5228 	struct qla_hw_data *ha = vha->hw;
5229 	mbx_cmd_t mc;
5230 	mbx_cmd_t *mcp = &mc;
5231 
5232 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
5233 	    "Entered %s.\n", __func__);
5234 
5235 	if (!IS_P3P_TYPE(ha))
5236 		return QLA_FUNCTION_FAILED;
5237 
5238 	memset(mcp, 0, sizeof(mbx_cmd_t));
5239 	mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5240 	mcp->mb[1] = 0;
5241 
5242 	mcp->out_mb = MBX_1|MBX_0;
5243 	mcp->in_mb = MBX_0;
5244 	mcp->tov = 30;
5245 	mcp->flags = 0;
5246 
5247 	rval = qla2x00_mailbox_command(vha, mcp);
5248 	if (rval != QLA_SUCCESS) {
5249 		ql_dbg(ql_dbg_mbx, vha, 0x100c,
5250 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5251 	} else {
5252 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
5253 		    "Done %s.\n", __func__);
5254 	}
5255 
5256 	return rval;
5257 }
5258 
5259 int
5260 qla82xx_md_get_template_size(scsi_qla_host_t *vha)
5261 {
5262 	struct qla_hw_data *ha = vha->hw;
5263 	mbx_cmd_t mc;
5264 	mbx_cmd_t *mcp = &mc;
5265 	int rval = QLA_FUNCTION_FAILED;
5266 
5267 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
5268 	    "Entered %s.\n", __func__);
5269 
5270 	memset(mcp->mb, 0 , sizeof(mcp->mb));
5271 	mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5272 	mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5273 	mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
5274 	mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
5275 
5276 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5277 	mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5278 	    MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5279 
5280 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5281 	mcp->tov = MBX_TOV_SECONDS;
5282 	rval = qla2x00_mailbox_command(vha, mcp);
5283 
5284 	/* Always copy back return mailbox values. */
5285 	if (rval != QLA_SUCCESS) {
5286 		ql_dbg(ql_dbg_mbx, vha, 0x1120,
5287 		    "mailbox command FAILED=0x%x, subcode=%x.\n",
5288 		    (mcp->mb[1] << 16) | mcp->mb[0],
5289 		    (mcp->mb[3] << 16) | mcp->mb[2]);
5290 	} else {
5291 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
5292 		    "Done %s.\n", __func__);
5293 		ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
5294 		if (!ha->md_template_size) {
5295 			ql_dbg(ql_dbg_mbx, vha, 0x1122,
5296 			    "Null template size obtained.\n");
5297 			rval = QLA_FUNCTION_FAILED;
5298 		}
5299 	}
5300 	return rval;
5301 }
5302 
5303 int
5304 qla82xx_md_get_template(scsi_qla_host_t *vha)
5305 {
5306 	struct qla_hw_data *ha = vha->hw;
5307 	mbx_cmd_t mc;
5308 	mbx_cmd_t *mcp = &mc;
5309 	int rval = QLA_FUNCTION_FAILED;
5310 
5311 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
5312 	    "Entered %s.\n", __func__);
5313 
5314 	ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5315 	   ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5316 	if (!ha->md_tmplt_hdr) {
5317 		ql_log(ql_log_warn, vha, 0x1124,
5318 		    "Unable to allocate memory for Minidump template.\n");
5319 		return rval;
5320 	}
5321 
5322 	memset(mcp->mb, 0 , sizeof(mcp->mb));
5323 	mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5324 	mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5325 	mcp->mb[2] = LSW(RQST_TMPLT);
5326 	mcp->mb[3] = MSW(RQST_TMPLT);
5327 	mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5328 	mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5329 	mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5330 	mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5331 	mcp->mb[8] = LSW(ha->md_template_size);
5332 	mcp->mb[9] = MSW(ha->md_template_size);
5333 
5334 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5335 	mcp->tov = MBX_TOV_SECONDS;
5336 	mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5337 	    MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5338 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5339 	rval = qla2x00_mailbox_command(vha, mcp);
5340 
5341 	if (rval != QLA_SUCCESS) {
5342 		ql_dbg(ql_dbg_mbx, vha, 0x1125,
5343 		    "mailbox command FAILED=0x%x, subcode=%x.\n",
5344 		    ((mcp->mb[1] << 16) | mcp->mb[0]),
5345 		    ((mcp->mb[3] << 16) | mcp->mb[2]));
5346 	} else
5347 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5348 		    "Done %s.\n", __func__);
5349 	return rval;
5350 }
5351 
5352 int
5353 qla8044_md_get_template(scsi_qla_host_t *vha)
5354 {
5355 	struct qla_hw_data *ha = vha->hw;
5356 	mbx_cmd_t mc;
5357 	mbx_cmd_t *mcp = &mc;
5358 	int rval = QLA_FUNCTION_FAILED;
5359 	int offset = 0, size = MINIDUMP_SIZE_36K;
5360 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5361 	    "Entered %s.\n", __func__);
5362 
5363 	ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5364 	   ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5365 	if (!ha->md_tmplt_hdr) {
5366 		ql_log(ql_log_warn, vha, 0xb11b,
5367 		    "Unable to allocate memory for Minidump template.\n");
5368 		return rval;
5369 	}
5370 
5371 	memset(mcp->mb, 0 , sizeof(mcp->mb));
5372 	while (offset < ha->md_template_size) {
5373 		mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5374 		mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5375 		mcp->mb[2] = LSW(RQST_TMPLT);
5376 		mcp->mb[3] = MSW(RQST_TMPLT);
5377 		mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5378 		mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5379 		mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5380 		mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5381 		mcp->mb[8] = LSW(size);
5382 		mcp->mb[9] = MSW(size);
5383 		mcp->mb[10] = offset & 0x0000FFFF;
5384 		mcp->mb[11] = offset & 0xFFFF0000;
5385 		mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5386 		mcp->tov = MBX_TOV_SECONDS;
5387 		mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5388 			MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5389 		mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5390 		rval = qla2x00_mailbox_command(vha, mcp);
5391 
5392 		if (rval != QLA_SUCCESS) {
5393 			ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5394 				"mailbox command FAILED=0x%x, subcode=%x.\n",
5395 				((mcp->mb[1] << 16) | mcp->mb[0]),
5396 				((mcp->mb[3] << 16) | mcp->mb[2]));
5397 			return rval;
5398 		} else
5399 			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5400 				"Done %s.\n", __func__);
5401 		offset = offset + size;
5402 	}
5403 	return rval;
5404 }
5405 
5406 int
5407 qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5408 {
5409 	int rval;
5410 	struct qla_hw_data *ha = vha->hw;
5411 	mbx_cmd_t mc;
5412 	mbx_cmd_t *mcp = &mc;
5413 
5414 	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5415 		return QLA_FUNCTION_FAILED;
5416 
5417 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5418 	    "Entered %s.\n", __func__);
5419 
5420 	memset(mcp, 0, sizeof(mbx_cmd_t));
5421 	mcp->mb[0] = MBC_SET_LED_CONFIG;
5422 	mcp->mb[1] = led_cfg[0];
5423 	mcp->mb[2] = led_cfg[1];
5424 	if (IS_QLA8031(ha)) {
5425 		mcp->mb[3] = led_cfg[2];
5426 		mcp->mb[4] = led_cfg[3];
5427 		mcp->mb[5] = led_cfg[4];
5428 		mcp->mb[6] = led_cfg[5];
5429 	}
5430 
5431 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
5432 	if (IS_QLA8031(ha))
5433 		mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5434 	mcp->in_mb = MBX_0;
5435 	mcp->tov = 30;
5436 	mcp->flags = 0;
5437 
5438 	rval = qla2x00_mailbox_command(vha, mcp);
5439 	if (rval != QLA_SUCCESS) {
5440 		ql_dbg(ql_dbg_mbx, vha, 0x1134,
5441 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5442 	} else {
5443 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5444 		    "Done %s.\n", __func__);
5445 	}
5446 
5447 	return rval;
5448 }
5449 
5450 int
5451 qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5452 {
5453 	int rval;
5454 	struct qla_hw_data *ha = vha->hw;
5455 	mbx_cmd_t mc;
5456 	mbx_cmd_t *mcp = &mc;
5457 
5458 	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5459 		return QLA_FUNCTION_FAILED;
5460 
5461 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5462 	    "Entered %s.\n", __func__);
5463 
5464 	memset(mcp, 0, sizeof(mbx_cmd_t));
5465 	mcp->mb[0] = MBC_GET_LED_CONFIG;
5466 
5467 	mcp->out_mb = MBX_0;
5468 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
5469 	if (IS_QLA8031(ha))
5470 		mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5471 	mcp->tov = 30;
5472 	mcp->flags = 0;
5473 
5474 	rval = qla2x00_mailbox_command(vha, mcp);
5475 	if (rval != QLA_SUCCESS) {
5476 		ql_dbg(ql_dbg_mbx, vha, 0x1137,
5477 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5478 	} else {
5479 		led_cfg[0] = mcp->mb[1];
5480 		led_cfg[1] = mcp->mb[2];
5481 		if (IS_QLA8031(ha)) {
5482 			led_cfg[2] = mcp->mb[3];
5483 			led_cfg[3] = mcp->mb[4];
5484 			led_cfg[4] = mcp->mb[5];
5485 			led_cfg[5] = mcp->mb[6];
5486 		}
5487 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5488 		    "Done %s.\n", __func__);
5489 	}
5490 
5491 	return rval;
5492 }
5493 
5494 int
5495 qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5496 {
5497 	int rval;
5498 	struct qla_hw_data *ha = vha->hw;
5499 	mbx_cmd_t mc;
5500 	mbx_cmd_t *mcp = &mc;
5501 
5502 	if (!IS_P3P_TYPE(ha))
5503 		return QLA_FUNCTION_FAILED;
5504 
5505 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
5506 		"Entered %s.\n", __func__);
5507 
5508 	memset(mcp, 0, sizeof(mbx_cmd_t));
5509 	mcp->mb[0] = MBC_SET_LED_CONFIG;
5510 	if (enable)
5511 		mcp->mb[7] = 0xE;
5512 	else
5513 		mcp->mb[7] = 0xD;
5514 
5515 	mcp->out_mb = MBX_7|MBX_0;
5516 	mcp->in_mb = MBX_0;
5517 	mcp->tov = MBX_TOV_SECONDS;
5518 	mcp->flags = 0;
5519 
5520 	rval = qla2x00_mailbox_command(vha, mcp);
5521 	if (rval != QLA_SUCCESS) {
5522 		ql_dbg(ql_dbg_mbx, vha, 0x1128,
5523 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5524 	} else {
5525 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
5526 		    "Done %s.\n", __func__);
5527 	}
5528 
5529 	return rval;
5530 }
5531 
5532 int
5533 qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
5534 {
5535 	int rval;
5536 	struct qla_hw_data *ha = vha->hw;
5537 	mbx_cmd_t mc;
5538 	mbx_cmd_t *mcp = &mc;
5539 
5540 	if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
5541 		return QLA_FUNCTION_FAILED;
5542 
5543 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5544 	    "Entered %s.\n", __func__);
5545 
5546 	mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5547 	mcp->mb[1] = LSW(reg);
5548 	mcp->mb[2] = MSW(reg);
5549 	mcp->mb[3] = LSW(data);
5550 	mcp->mb[4] = MSW(data);
5551 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5552 
5553 	mcp->in_mb = MBX_1|MBX_0;
5554 	mcp->tov = MBX_TOV_SECONDS;
5555 	mcp->flags = 0;
5556 	rval = qla2x00_mailbox_command(vha, mcp);
5557 
5558 	if (rval != QLA_SUCCESS) {
5559 		ql_dbg(ql_dbg_mbx, vha, 0x1131,
5560 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5561 	} else {
5562 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
5563 		    "Done %s.\n", __func__);
5564 	}
5565 
5566 	return rval;
5567 }
5568 
5569 int
5570 qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5571 {
5572 	int rval;
5573 	struct qla_hw_data *ha = vha->hw;
5574 	mbx_cmd_t mc;
5575 	mbx_cmd_t *mcp = &mc;
5576 
5577 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
5578 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
5579 		    "Implicit LOGO Unsupported.\n");
5580 		return QLA_FUNCTION_FAILED;
5581 	}
5582 
5583 
5584 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5585 	    "Entering %s.\n",  __func__);
5586 
5587 	/* Perform Implicit LOGO. */
5588 	mcp->mb[0] = MBC_PORT_LOGOUT;
5589 	mcp->mb[1] = fcport->loop_id;
5590 	mcp->mb[10] = BIT_15;
5591 	mcp->out_mb = MBX_10|MBX_1|MBX_0;
5592 	mcp->in_mb = MBX_0;
5593 	mcp->tov = MBX_TOV_SECONDS;
5594 	mcp->flags = 0;
5595 	rval = qla2x00_mailbox_command(vha, mcp);
5596 	if (rval != QLA_SUCCESS)
5597 		ql_dbg(ql_dbg_mbx, vha, 0x113d,
5598 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5599 	else
5600 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5601 		    "Done %s.\n", __func__);
5602 
5603 	return rval;
5604 }
5605 
5606 int
5607 qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5608 {
5609 	int rval;
5610 	mbx_cmd_t mc;
5611 	mbx_cmd_t *mcp = &mc;
5612 	struct qla_hw_data *ha = vha->hw;
5613 	unsigned long retry_max_time = jiffies + (2 * HZ);
5614 
5615 	if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
5616 		return QLA_FUNCTION_FAILED;
5617 
5618 	ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5619 
5620 retry_rd_reg:
5621 	mcp->mb[0] = MBC_READ_REMOTE_REG;
5622 	mcp->mb[1] = LSW(reg);
5623 	mcp->mb[2] = MSW(reg);
5624 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
5625 	mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5626 	mcp->tov = MBX_TOV_SECONDS;
5627 	mcp->flags = 0;
5628 	rval = qla2x00_mailbox_command(vha, mcp);
5629 
5630 	if (rval != QLA_SUCCESS) {
5631 		ql_dbg(ql_dbg_mbx, vha, 0x114c,
5632 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
5633 		    rval, mcp->mb[0], mcp->mb[1]);
5634 	} else {
5635 		*data = (mcp->mb[3] | (mcp->mb[4] << 16));
5636 		if (*data == QLA8XXX_BAD_VALUE) {
5637 			/*
5638 			 * During soft-reset CAMRAM register reads might
5639 			 * return 0xbad0bad0. So retry for MAX of 2 sec
5640 			 * while reading camram registers.
5641 			 */
5642 			if (time_after(jiffies, retry_max_time)) {
5643 				ql_dbg(ql_dbg_mbx, vha, 0x1141,
5644 				    "Failure to read CAMRAM register. "
5645 				    "data=0x%x.\n", *data);
5646 				return QLA_FUNCTION_FAILED;
5647 			}
5648 			msleep(100);
5649 			goto retry_rd_reg;
5650 		}
5651 		ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5652 	}
5653 
5654 	return rval;
5655 }
5656 
5657 int
5658 qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5659 {
5660 	int rval;
5661 	mbx_cmd_t mc;
5662 	mbx_cmd_t *mcp = &mc;
5663 	struct qla_hw_data *ha = vha->hw;
5664 
5665 	if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
5666 		return QLA_FUNCTION_FAILED;
5667 
5668 	ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5669 
5670 	mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5671 	mcp->out_mb = MBX_0;
5672 	mcp->in_mb = MBX_1|MBX_0;
5673 	mcp->tov = MBX_TOV_SECONDS;
5674 	mcp->flags = 0;
5675 	rval = qla2x00_mailbox_command(vha, mcp);
5676 
5677 	if (rval != QLA_SUCCESS) {
5678 		ql_dbg(ql_dbg_mbx, vha, 0x1144,
5679 		    "Failed=%x mb[0]=%x mb[1]=%x.\n",
5680 		    rval, mcp->mb[0], mcp->mb[1]);
5681 		ha->isp_ops->fw_dump(vha, 0);
5682 	} else {
5683 		ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5684 	}
5685 
5686 	return rval;
5687 }
5688 
5689 int
5690 qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5691 	uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5692 {
5693 	int rval;
5694 	mbx_cmd_t mc;
5695 	mbx_cmd_t *mcp = &mc;
5696 	uint8_t subcode = (uint8_t)options;
5697 	struct qla_hw_data *ha = vha->hw;
5698 
5699 	if (!IS_QLA8031(ha))
5700 		return QLA_FUNCTION_FAILED;
5701 
5702 	ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5703 
5704 	mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5705 	mcp->mb[1] = options;
5706 	mcp->out_mb = MBX_1|MBX_0;
5707 	if (subcode & BIT_2) {
5708 		mcp->mb[2] = LSW(start_addr);
5709 		mcp->mb[3] = MSW(start_addr);
5710 		mcp->mb[4] = LSW(end_addr);
5711 		mcp->mb[5] = MSW(end_addr);
5712 		mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5713 	}
5714 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
5715 	if (!(subcode & (BIT_2 | BIT_5)))
5716 		mcp->in_mb |= MBX_4|MBX_3;
5717 	mcp->tov = MBX_TOV_SECONDS;
5718 	mcp->flags = 0;
5719 	rval = qla2x00_mailbox_command(vha, mcp);
5720 
5721 	if (rval != QLA_SUCCESS) {
5722 		ql_dbg(ql_dbg_mbx, vha, 0x1147,
5723 		    "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5724 		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5725 		    mcp->mb[4]);
5726 		ha->isp_ops->fw_dump(vha, 0);
5727 	} else {
5728 		if (subcode & BIT_5)
5729 			*sector_size = mcp->mb[1];
5730 		else if (subcode & (BIT_6 | BIT_7)) {
5731 			ql_dbg(ql_dbg_mbx, vha, 0x1148,
5732 			    "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5733 		} else if (subcode & (BIT_3 | BIT_4)) {
5734 			ql_dbg(ql_dbg_mbx, vha, 0x1149,
5735 			    "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5736 		}
5737 		ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5738 	}
5739 
5740 	return rval;
5741 }
5742 
5743 int
5744 qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5745 	uint32_t size)
5746 {
5747 	int rval;
5748 	mbx_cmd_t mc;
5749 	mbx_cmd_t *mcp = &mc;
5750 
5751 	if (!IS_MCTP_CAPABLE(vha->hw))
5752 		return QLA_FUNCTION_FAILED;
5753 
5754 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5755 	    "Entered %s.\n", __func__);
5756 
5757 	mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5758 	mcp->mb[1] = LSW(addr);
5759 	mcp->mb[2] = MSW(req_dma);
5760 	mcp->mb[3] = LSW(req_dma);
5761 	mcp->mb[4] = MSW(size);
5762 	mcp->mb[5] = LSW(size);
5763 	mcp->mb[6] = MSW(MSD(req_dma));
5764 	mcp->mb[7] = LSW(MSD(req_dma));
5765 	mcp->mb[8] = MSW(addr);
5766 	/* Setting RAM ID to valid */
5767 	mcp->mb[10] |= BIT_7;
5768 	/* For MCTP RAM ID is 0x40 */
5769 	mcp->mb[10] |= 0x40;
5770 
5771 	mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5772 	    MBX_0;
5773 
5774 	mcp->in_mb = MBX_0;
5775 	mcp->tov = MBX_TOV_SECONDS;
5776 	mcp->flags = 0;
5777 	rval = qla2x00_mailbox_command(vha, mcp);
5778 
5779 	if (rval != QLA_SUCCESS) {
5780 		ql_dbg(ql_dbg_mbx, vha, 0x114e,
5781 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5782 	} else {
5783 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5784 		    "Done %s.\n", __func__);
5785 	}
5786 
5787 	return rval;
5788 }
5789 
5790 int
5791 qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
5792 	void *dd_buf, uint size, uint options)
5793 {
5794 	int rval;
5795 	mbx_cmd_t mc;
5796 	mbx_cmd_t *mcp = &mc;
5797 	dma_addr_t dd_dma;
5798 
5799 	if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
5800 		return QLA_FUNCTION_FAILED;
5801 
5802 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
5803 	    "Entered %s.\n", __func__);
5804 
5805 	dd_dma = dma_map_single(&vha->hw->pdev->dev,
5806 	    dd_buf, size, DMA_FROM_DEVICE);
5807 	if (!dd_dma) {
5808 		ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
5809 		return QLA_MEMORY_ALLOC_FAILED;
5810 	}
5811 
5812 	memset(dd_buf, 0, size);
5813 
5814 	mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
5815 	mcp->mb[1] = options;
5816 	mcp->mb[2] = MSW(LSD(dd_dma));
5817 	mcp->mb[3] = LSW(LSD(dd_dma));
5818 	mcp->mb[6] = MSW(MSD(dd_dma));
5819 	mcp->mb[7] = LSW(MSD(dd_dma));
5820 	mcp->mb[8] = size;
5821 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
5822 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5823 	mcp->buf_size = size;
5824 	mcp->flags = MBX_DMA_IN;
5825 	mcp->tov = MBX_TOV_SECONDS * 4;
5826 	rval = qla2x00_mailbox_command(vha, mcp);
5827 
5828 	if (rval != QLA_SUCCESS) {
5829 		ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
5830 	} else {
5831 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
5832 		    "Done %s.\n", __func__);
5833 	}
5834 
5835 	dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
5836 	    size, DMA_FROM_DEVICE);
5837 
5838 	return rval;
5839 }
5840 
5841 static void qla2x00_async_mb_sp_done(void *s, int res)
5842 {
5843 	struct srb *sp = s;
5844 
5845 	sp->u.iocb_cmd.u.mbx.rc = res;
5846 
5847 	complete(&sp->u.iocb_cmd.u.mbx.comp);
5848 	/* don't free sp here. Let the caller do the free */
5849 }
5850 
5851 /*
5852  * This mailbox uses the iocb interface to send MB command.
5853  * This allows non-critial (non chip setup) command to go
5854  * out in parrallel.
5855  */
5856 int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
5857 {
5858 	int rval = QLA_FUNCTION_FAILED;
5859 	srb_t *sp;
5860 	struct srb_iocb *c;
5861 
5862 	if (!vha->hw->flags.fw_started)
5863 		goto done;
5864 
5865 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
5866 	if (!sp)
5867 		goto done;
5868 
5869 	sp->type = SRB_MB_IOCB;
5870 	sp->name = mb_to_str(mcp->mb[0]);
5871 
5872 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
5873 
5874 	memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
5875 
5876 	c = &sp->u.iocb_cmd;
5877 	c->timeout = qla2x00_async_iocb_timeout;
5878 	init_completion(&c->u.mbx.comp);
5879 
5880 	sp->done = qla2x00_async_mb_sp_done;
5881 
5882 	rval = qla2x00_start_sp(sp);
5883 	if (rval != QLA_SUCCESS) {
5884 		ql_dbg(ql_dbg_mbx, vha, 0xffff,
5885 		    "%s: %s Failed submission. %x.\n",
5886 		    __func__, sp->name, rval);
5887 		goto done_free_sp;
5888 	}
5889 
5890 	ql_dbg(ql_dbg_mbx, vha, 0xffff, "MB:%s hndl %x submitted\n",
5891 	    sp->name, sp->handle);
5892 
5893 	wait_for_completion(&c->u.mbx.comp);
5894 	memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
5895 
5896 	rval = c->u.mbx.rc;
5897 	switch (rval) {
5898 	case QLA_FUNCTION_TIMEOUT:
5899 		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Timeout. %x.\n",
5900 		    __func__, sp->name, rval);
5901 		break;
5902 	case  QLA_SUCCESS:
5903 		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s done.\n",
5904 		    __func__, sp->name);
5905 		sp->free(sp);
5906 		break;
5907 	default:
5908 		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Failed. %x.\n",
5909 		    __func__, sp->name, rval);
5910 		sp->free(sp);
5911 		break;
5912 	}
5913 
5914 	return rval;
5915 
5916 done_free_sp:
5917 	sp->free(sp);
5918 done:
5919 	return rval;
5920 }
5921 
5922 /*
5923  * qla24xx_gpdb_wait
5924  * NOTE: Do not call this routine from DPC thread
5925  */
5926 int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
5927 {
5928 	int rval = QLA_FUNCTION_FAILED;
5929 	dma_addr_t pd_dma;
5930 	struct port_database_24xx *pd;
5931 	struct qla_hw_data *ha = vha->hw;
5932 	mbx_cmd_t mc;
5933 
5934 	if (!vha->hw->flags.fw_started)
5935 		goto done;
5936 
5937 	pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
5938 	if (pd  == NULL) {
5939 		ql_log(ql_log_warn, vha, 0xffff,
5940 			"Failed to allocate port database structure.\n");
5941 		goto done_free_sp;
5942 	}
5943 	memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
5944 
5945 	memset(&mc, 0, sizeof(mc));
5946 	mc.mb[0] = MBC_GET_PORT_DATABASE;
5947 	mc.mb[1] = cpu_to_le16(fcport->loop_id);
5948 	mc.mb[2] = MSW(pd_dma);
5949 	mc.mb[3] = LSW(pd_dma);
5950 	mc.mb[6] = MSW(MSD(pd_dma));
5951 	mc.mb[7] = LSW(MSD(pd_dma));
5952 	mc.mb[9] = cpu_to_le16(vha->vp_idx);
5953 	mc.mb[10] = cpu_to_le16((uint16_t)opt);
5954 
5955 	rval = qla24xx_send_mb_cmd(vha, &mc);
5956 	if (rval != QLA_SUCCESS) {
5957 		ql_dbg(ql_dbg_mbx, vha, 0xffff,
5958 		    "%s: %8phC fail\n", __func__, fcport->port_name);
5959 		goto done_free_sp;
5960 	}
5961 
5962 	rval = __qla24xx_parse_gpdb(vha, fcport, pd);
5963 
5964 	ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %8phC done\n",
5965 	    __func__, fcport->port_name);
5966 
5967 done_free_sp:
5968 	if (pd)
5969 		dma_pool_free(ha->s_dma_pool, pd, pd_dma);
5970 done:
5971 	return rval;
5972 }
5973 
5974 int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
5975     struct port_database_24xx *pd)
5976 {
5977 	int rval = QLA_SUCCESS;
5978 	uint64_t zero = 0;
5979 
5980 	/* Check for logged in state. */
5981 	if (pd->current_login_state != PDS_PRLI_COMPLETE &&
5982 		pd->last_login_state != PDS_PRLI_COMPLETE) {
5983 		ql_dbg(ql_dbg_mbx, vha, 0xffff,
5984 			   "Unable to verify login-state (%x/%x) for "
5985 			   "loop_id %x.\n", pd->current_login_state,
5986 			   pd->last_login_state, fcport->loop_id);
5987 		rval = QLA_FUNCTION_FAILED;
5988 		goto gpd_error_out;
5989 	}
5990 
5991 	if (fcport->loop_id == FC_NO_LOOP_ID ||
5992 	    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
5993 	     memcmp(fcport->port_name, pd->port_name, 8))) {
5994 		/* We lost the device mid way. */
5995 		rval = QLA_NOT_LOGGED_IN;
5996 		goto gpd_error_out;
5997 	}
5998 
5999 	/* Names are little-endian. */
6000 	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
6001 	memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
6002 
6003 	/* Get port_id of device. */
6004 	fcport->d_id.b.domain = pd->port_id[0];
6005 	fcport->d_id.b.area = pd->port_id[1];
6006 	fcport->d_id.b.al_pa = pd->port_id[2];
6007 	fcport->d_id.b.rsvd_1 = 0;
6008 
6009 	/* If not target must be initiator or unknown type. */
6010 	if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
6011 		fcport->port_type = FCT_INITIATOR;
6012 	else
6013 		fcport->port_type = FCT_TARGET;
6014 
6015 	/* Passback COS information. */
6016 	fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
6017 		FC_COS_CLASS2 : FC_COS_CLASS3;
6018 
6019 	if (pd->prli_svc_param_word_3[0] & BIT_7) {
6020 		fcport->flags |= FCF_CONF_COMP_SUPPORTED;
6021 		fcport->conf_compl_supported = 1;
6022 	}
6023 
6024 gpd_error_out:
6025 	return rval;
6026 }
6027 
6028 /*
6029  * qla24xx_gidlist__wait
6030  * NOTE: don't call this routine from DPC thread.
6031  */
6032 int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
6033 	void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
6034 {
6035 	int rval = QLA_FUNCTION_FAILED;
6036 	mbx_cmd_t mc;
6037 
6038 	if (!vha->hw->flags.fw_started)
6039 		goto done;
6040 
6041 	memset(&mc, 0, sizeof(mc));
6042 	mc.mb[0] = MBC_GET_ID_LIST;
6043 	mc.mb[2] = MSW(id_list_dma);
6044 	mc.mb[3] = LSW(id_list_dma);
6045 	mc.mb[6] = MSW(MSD(id_list_dma));
6046 	mc.mb[7] = LSW(MSD(id_list_dma));
6047 	mc.mb[8] = 0;
6048 	mc.mb[9] = cpu_to_le16(vha->vp_idx);
6049 
6050 	rval = qla24xx_send_mb_cmd(vha, &mc);
6051 	if (rval != QLA_SUCCESS) {
6052 		ql_dbg(ql_dbg_mbx, vha, 0xffff,
6053 			"%s:  fail\n", __func__);
6054 	} else {
6055 		*entries = mc.mb[1];
6056 		ql_dbg(ql_dbg_mbx, vha, 0xffff,
6057 			"%s:  done\n", __func__);
6058 	}
6059 done:
6060 	return rval;
6061 }
6062