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