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