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