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