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