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