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