2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /* Copyright 2010 QLogic Corporation */
23
24 /*
25 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 */
27
28 #pragma ident "Copyright 2010 QLogic Corporation; ql_mbx.c"
29
30 /*
31 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32 *
33 * ***********************************************************************
34 * * **
35 * * NOTICE **
36 * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
37 * * ALL RIGHTS RESERVED **
38 * * **
39 * ***********************************************************************
40 *
41 */
42
43 #include <ql_apps.h>
44 #include <ql_api.h>
45 #include <ql_debug.h>
46 #include <ql_iocb.h>
47 #include <ql_isr.h>
48 #include <ql_mbx.h>
49 #include <ql_xioctl.h>
50
51 /*
52 * Local data
53 */
54
55 /*
56 * Local prototypes
57 */
58 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
59 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint16_t,
60 uint32_t, uint16_t);
61 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
62 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
63 caddr_t, uint32_t);
64 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
65 uint32_t);
66 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
67 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
68
69 /*
70 * ql_mailbox_command
71 * Issue mailbox command and waits for completion.
72 *
73 * Input:
74 * ha = adapter state pointer.
75 * mcp = mailbox command parameter structure pointer.
76 *
77 * Returns:
78 * ql local function return status code.
79 *
80 * Context:
81 * Kernel context.
82 */
83 static int
84 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
85 {
86 uint16_t cnt;
87 uint32_t data;
88 clock_t timer, cv_stat;
89 int rval;
90 uint32_t set_flags = 0;
91 uint32_t reset_flags = 0;
92 ql_adapter_state_t *ha = vha->pha;
93 int mbx_cmd = mcp->mb[0];
94
95 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, mbx_cmd);
96
97 /* Acquire mailbox register lock. */
98 MBX_REGISTER_LOCK(ha);
99
100 /* Check for mailbox available, if not wait for signal. */
101 while (ha->mailbox_flags & MBX_BUSY_FLG ||
102 (CFG_IST(ha, CFG_CTRL_8021) &&
103 RD32_IO_REG(ha, nx_host_int) & NX_MBX_CMD)) {
104 ha->mailbox_flags = (uint8_t)
105 (ha->mailbox_flags | MBX_WANT_FLG);
106
107 if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
108 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
109 MBX_REGISTER_UNLOCK(ha);
110 return (QL_LOCK_TIMEOUT);
111 }
112
113 /* Set timeout after command that is running. */
114 timer = (mcp->timeout + 20) * drv_usectohz(1000000);
115 cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
116 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
117 if (cv_stat == -1 || cv_stat == 0) {
118 /*
119 * The timeout time 'timer' was
120 * reached without the condition
121 * being signaled.
122 */
123 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
124 ~MBX_WANT_FLG);
125 cv_broadcast(&ha->cv_mbx_wait);
126
127 /* Release mailbox register lock. */
128 MBX_REGISTER_UNLOCK(ha);
129
130 if (cv_stat == 0) {
131 EL(vha, "waiting for availability aborted, "
132 "cmd=%xh\n", mcp->mb[0]);
133 return (QL_ABORTED);
134 }
136 return (QL_LOCK_TIMEOUT);
137 }
138 }
139
140 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
141
142 /* Structure pointer for return mailbox registers. */
143 ha->mcp = mcp;
144
145 /* Load mailbox registers. */
146 data = mcp->out_mb;
147 for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
148 if (data & MBX_0) {
149 WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
150 }
151 data >>= 1;
152 }
153
154 /* Issue set host interrupt command. */
155 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
156 if (CFG_IST(ha, CFG_CTRL_8021)) {
157 WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
158 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
159 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
160 } else {
161 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
162 }
163
164 /* Wait for command to complete. */
165 if (ha->flags & INTERRUPTS_ENABLED &&
166 !(ha->task_daemon_flags & (TASK_THREAD_CALLED |
167 TASK_DAEMON_POWERING_DOWN)) &&
168 !ddi_in_panic()) {
169 timer = mcp->timeout * drv_usectohz(1000000);
170 while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
171 !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
172
173 if (cv_reltimedwait(&ha->cv_mbx_intr,
174 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
175 /*
176 * The timeout time 'timer' was
177 * reached without the condition
178 * being signaled.
179 */
180 MBX_REGISTER_UNLOCK(ha);
181 while (INTERRUPT_PENDING(ha)) {
182 (void) ql_isr((caddr_t)ha);
183 INTR_LOCK(ha);
184 ha->intr_claimed = B_TRUE;
185 INTR_UNLOCK(ha);
186 }
187 MBX_REGISTER_LOCK(ha);
188 break;
189 }
190 }
191 } else {
192 /* Release mailbox register lock. */
193 MBX_REGISTER_UNLOCK(ha);
194
195 /* Acquire interrupt lock. */
196 for (timer = mcp->timeout * 100; timer; timer--) {
197 /* Check for pending interrupts. */
198 while (INTERRUPT_PENDING(ha)) {
199 (void) ql_isr((caddr_t)ha);
208 }
209 if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
210 ha->task_daemon_flags & ISP_ABORT_NEEDED) {
211 break;
212 } else if (!ddi_in_panic() && timer % 101 == 0) {
213 delay(drv_usectohz(10000));
214 } else {
215 drv_usecwait(10000);
216 }
217 }
218
219 /* Acquire mailbox register lock. */
220 MBX_REGISTER_LOCK(ha);
221 }
222
223 /* Mailbox command timeout? */
224 if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
225 ha->mailbox_flags & MBX_ABORT) {
226 rval = QL_ABORTED;
227 } else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
228 if (!CFG_IST(ha, CFG_CTRL_8021)) {
229 if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
230 (void) ql_binary_fw_dump(ha, FALSE);
231 }
232 EL(vha, "command timeout, isp_abort_needed\n");
233 set_flags |= ISP_ABORT_NEEDED;
234 }
235 rval = QL_FUNCTION_TIMEOUT;
236 } else {
237 ha->mailbox_flags = (uint8_t)
238 (ha->mailbox_flags & ~MBX_INTERRUPT);
239 /*
240 * This is the expected completion path so
241 * return the actual mbx cmd completion status.
242 */
243 rval = mcp->mb[0];
244 }
245
246 /*
247 * Clear outbound to risc mailbox registers per spec. The exception
248 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
249 * so avoid writing them.
250 */
251 if (ha->cfg_flags & CFG_CTRL_2200) {
252 data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
253 } else {
254 data = (mcp->out_mb >> 1);
255 }
256 for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
257 if (data & MBX_0) {
258 WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
259 }
260 data >>= 1;
261 }
262
263 /* Reset busy status. */
264 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
265 ~(MBX_BUSY_FLG | MBX_ABORT));
266 ha->mcp = NULL;
267
268 /* If thread is waiting for mailbox go signal it to start. */
269 if (ha->mailbox_flags & MBX_WANT_FLG) {
270 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
271 ~MBX_WANT_FLG);
272 cv_broadcast(&ha->cv_mbx_wait);
273 }
274
275 /* Release mailbox register lock. */
276 MBX_REGISTER_UNLOCK(ha);
277
278 if (set_flags != 0 || reset_flags != 0) {
279 ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
280 }
281
282 if (rval != QL_SUCCESS) {
283 EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
284 mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
285 } else {
286 /*EMPTY*/
287 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
288 }
289
290 return (rval);
291 }
292
293 /*
294 * ql_setup_mbox_dma_resources
295 * Prepare the data for a mailbox dma transfer.
296 *
297 * Input:
298 * ha = adapter state pointer.
299 * mem_desc = descriptor to contain the dma resource information.
300 * data = pointer to the data.
301 * size = size of the data in bytes.
302 *
303 * Returns:
304 * ql local function return status code.
305 *
306 * Context:
307 * Kernel context.
410 * ha = adapter state pointer.
411 * ha->ip_init_ctrl_blk = setup for transmit.
412 *
413 * Returns:
414 * ql local function return status code.
415 *
416 * Context:
417 * Kernel context.
418 */
419 int
420 ql_initialize_ip(ql_adapter_state_t *ha)
421 {
422 ql_link_t *link;
423 ql_tgt_t *tq;
424 uint16_t index;
425 int rval;
426 dma_mem_t mem_desc;
427 mbx_cmd_t mc = {0};
428 mbx_cmd_t *mcp = &mc;
429
430 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
431
432 if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_258081)) ||
433 ha->vp_index != 0) {
434 ha->flags &= ~IP_INITIALIZED;
435 EL(ha, "HBA does not support IP\n");
436 return (QL_FUNCTION_FAILED);
437 }
438
439 ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
440 ha->rcvbuf_ring_index = 0;
441
442 /* Reset all sequence counts. */
443 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
444 for (link = ha->dev[index].first; link != NULL;
445 link = link->next) {
446 tq = link->base_address;
447 tq->ub_total_seg_cnt = 0;
448 }
449 }
450
451 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
452 (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
453 if (rval != QL_SUCCESS) {
454 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
455 return (rval);
456 }
457
458 mcp->mb[0] = MBC_INITIALIZE_IP;
459 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
460 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
461 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
462 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
463 mcp->mb[8] = 0;
464 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
465 mcp->in_mb = MBX_8|MBX_0;
466 mcp->timeout = MAILBOX_TOV;
467 rval = ql_mailbox_command(ha, mcp);
468
469 ql_free_dma_resource(ha, &mem_desc);
470
471 if (rval == QL_SUCCESS) {
472 ADAPTER_STATE_LOCK(ha);
473 ha->flags |= IP_INITIALIZED;
474 ADAPTER_STATE_UNLOCK(ha);
475 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
476 } else {
477 ha->flags &= ~IP_INITIALIZED;
478 EL(ha, "failed, rval = %xh\n", rval);
479 }
480 return (rval);
481 }
482
483 /*
484 * ql_shutdown_ip
485 * Disconnects firmware IP from system buffers.
486 *
487 * Input:
488 * ha = adapter state pointer.
489 *
490 * Returns:
491 * ql local function return status code.
492 *
493 * Context:
494 * Kernel context.
495 */
496 int
497 ql_shutdown_ip(ql_adapter_state_t *ha)
498 {
499 int rval;
500 mbx_cmd_t mc = {0};
501 mbx_cmd_t *mcp = &mc;
502 fc_unsol_buf_t *ubp;
503 ql_srb_t *sp;
504 uint16_t index;
505
506 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
507
508 mcp->mb[0] = MBC_UNLOAD_IP;
509 mcp->out_mb = MBX_0;
510 mcp->in_mb = MBX_0;
511 mcp->timeout = MAILBOX_TOV;
512 rval = ql_mailbox_command(ha, mcp);
513
514 ADAPTER_STATE_LOCK(ha);
515 QL_UB_LOCK(ha);
516 /* Return all unsolicited buffers that ISP-IP has. */
517 for (index = 0; index < QL_UB_LIMIT; index++) {
518 ubp = ha->ub_array[index];
519 if (ubp != NULL) {
520 sp = ubp->ub_fca_private;
521 sp->flags &= ~SRB_UB_IN_ISP;
522 }
523 }
524
525 ha->ub_outcnt = 0;
526 QL_UB_UNLOCK(ha);
527 ha->flags &= ~IP_INITIALIZED;
528 ADAPTER_STATE_UNLOCK(ha);
529
530 if (rval == QL_SUCCESS) {
531 /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
532 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
533 } else {
534 EL(ha, "failed, rval = %xh\n", rval);
535 }
536 return (rval);
537 }
538
539 /*
540 * ql_online_selftest
541 * Issue online self test mailbox command.
542 *
543 * Input:
544 * ha = adapter state pointer.
545 *
546 * Returns:
547 * ql local function return status code.
548 *
549 * Context:
550 * Kernel context.
551 */
552 int
553 ql_online_selftest(ql_adapter_state_t *ha)
554 {
555 int rval;
556 mbx_cmd_t mc = {0};
557 mbx_cmd_t *mcp = &mc;
558
559 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
560
561 mcp->mb[0] = MBC_ONLINE_SELF_TEST;
562 mcp->out_mb = MBX_0;
563 mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
564 mcp->timeout = MAILBOX_TOV;
565 rval = ql_mailbox_command(ha, mcp);
566
567 if (rval != QL_SUCCESS) {
568 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
569 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
570 } else {
571 /*EMPTY*/
572 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
573 }
574 return (rval);
575 }
576
577 /*
578 * ql_loop_back
579 * Issue diagnostic loop back frame mailbox command.
580 *
581 * Input:
582 * ha: adapter state pointer.
583 * findex: FCF index.
584 * lb: loop back parameter structure pointer.
585 *
586 * Returns:
587 * ql local function return status code.
588 *
589 * Context:
590 * Kernel context.
591 */
592 #ifndef apps_64bit
593 int
594 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
595 uint32_t h_xmit, uint32_t h_rcv)
596 {
597 int rval;
598 mbx_cmd_t mc = {0};
599 mbx_cmd_t *mcp = &mc;
600
601 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
602
603 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
604 mcp->mb[1] = lb->options;
605 mcp->mb[2] = findex;
606 mcp->mb[6] = LSW(h_rcv);
607 mcp->mb[7] = MSW(h_rcv);
608 mcp->mb[10] = LSW(lb->transfer_count);
609 mcp->mb[11] = MSW(lb->transfer_count);
610 mcp->mb[12] = lb->transfer_segment_count;
611 mcp->mb[13] = lb->receive_segment_count;
612 mcp->mb[14] = LSW(lb->transfer_data_address);
613 mcp->mb[15] = MSW(lb->transfer_data_address);
614 mcp->mb[16] = LSW(lb->receive_data_address);
615 mcp->mb[17] = MSW(lb->receive_data_address);
616 mcp->mb[18] = LSW(lb->iteration_count);
617 mcp->mb[19] = MSW(lb->iteration_count);
618 mcp->mb[20] = LSW(h_xmit);
619 mcp->mb[21] = MSW(h_xmit);
620 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
621 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
622 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
623 mcp->timeout = lb->iteration_count / 300;
624
625 if (mcp->timeout < MAILBOX_TOV) {
626 mcp->timeout = MAILBOX_TOV;
627 }
628
629 rval = ql_mailbox_command(ha, mcp);
630
631 if (rval != QL_SUCCESS) {
632 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
633 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
634 } else {
635 /*EMPTY*/
636 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
637 }
638 return (rval);
639 }
640 #else
641 int
642 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
643 {
644 int rval;
645 mbx_cmd_t mc = {0};
646 mbx_cmd_t *mcp = &mc;
647
648 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
649
650 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
651 mcp->mb[1] = lb->options;
652 mcp->mb[2] = findex;
653 mcp->mb[6] = LSW(h_rcv);
654 mcp->mb[7] = MSW(h_rcv);
655 mcp->mb[6] = LSW(MSD(lb->receive_data_address));
656 mcp->mb[7] = MSW(MSD(lb->receive_data_address));
657 mcp->mb[10] = LSW(lb->transfer_count);
658 mcp->mb[11] = MSW(lb->transfer_count);
659 mcp->mb[12] = lb->transfer_segment_count;
660 mcp->mb[13] = lb->receive_segment_count;
661 mcp->mb[14] = LSW(lb->transfer_data_address);
662 mcp->mb[15] = MSW(lb->transfer_data_address);
663 mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
664 mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
665 mcp->mb[16] = LSW(lb->receive_data_address);
666 mcp->mb[17] = MSW(lb->receive_data_address);
667 mcp->mb[16] = LSW(LSD(lb->receive_data_address));
668 mcp->mb[17] = MSW(LSD(lb->receive_data_address));
670 mcp->mb[19] = MSW(lb->iteration_count);
671 mcp->mb[20] = LSW(h_xmit);
672 mcp->mb[21] = MSW(h_xmit);
673 mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
674 mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
675 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
676 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
677 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
678 mcp->timeout = lb->iteration_count / 300;
679
680 if (mcp->timeout < MAILBOX_TOV) {
681 mcp->timeout = MAILBOX_TOV;
682 }
683
684 rval = ql_mailbox_command(ha, mcp);
685
686 if (rval != QL_SUCCESS) {
687 EL(ha, "failed, rval = %xh\n", rval);
688 } else {
689 /*EMPTY*/
690 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
691 }
692 return (rval);
693 }
694 #endif
695
696 /*
697 * ql_echo
698 * Issue an ELS echo using the user specified data to a user specified
699 * destination
700 *
701 * Input:
702 * ha: adapter state pointer.
703 * findex: FCF index.
704 * echo_pt: echo parameter structure pointer.
705 *
706 * Returns:
707 * ql local function return status code.
708 *
709 * Context:
710 * Kernel context.
711 */
712 int
713 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
714 {
715 int rval;
716 mbx_cmd_t mc = {0};
717 mbx_cmd_t *mcp = &mc;
718
719 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
720
721 mcp->mb[0] = MBC_ECHO; /* ECHO command */
722 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */
723 /* addressing (bit 6) and */
724 /* real echo (bit 15 */
725 mcp->mb[2] = findex;
726
727 /*
728 * I know this looks strange, using a field labled "not used"
729 * The way the ddi_dma_cookie_t structure/union is defined
730 * is a union of one 64 bit entity with an array of two 32
731 * bit enititys. Since we have routines to convert 32 bit
732 * entities into 16 bit entities it is easier to use
733 * both 32 bit union members then the one 64 bit union
734 * member
735 */
736 if (echo_pt->options & BIT_6) {
737 /* 64 bit addressing */
738 /* Receive data dest add in system memory bits 47-32 */
739 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
757 /* Transmit data source address in system memory bits 31-16 */
758 mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
759
760 /* Receive data destination address in system memory bits 15-0 */
761 mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
762
763 /* Receive data destination address in system memory bits 31-16 */
764 mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
765
766 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
767 MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
768 mcp->in_mb = MBX_3|MBX_1|MBX_0;
769 mcp->timeout = MAILBOX_TOV;
770
771 rval = ql_mailbox_command(ha, mcp);
772
773 if (rval != QL_SUCCESS) {
774 EL(ha, "failed, rval = %xh\n", rval);
775 } else {
776 /*EMPTY*/
777 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
778 }
779 return (rval);
780 }
781
782 /*
783 * ql_send_change_request
784 * Issue send change request mailbox command.
785 *
786 * Input:
787 * ha: adapter state pointer.
788 * fmt: Registration format.
789 *
790 * Returns:
791 * ql local function return status code.
792 *
793 * Context:
794 * Kernel context.
795 */
796 int
797 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
798 {
799 int rval;
800 mbx_cmd_t mc = {0};
801 mbx_cmd_t *mcp = &mc;
802
803 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
804
805 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
806 mcp->mb[1] = fmt;
807 mcp->out_mb = MBX_1|MBX_0;
808 if (ha->flags & VP_ENABLED) {
809 mcp->mb[9] = ha->vp_index;
810 mcp->out_mb |= MBX_9;
811 }
812 mcp->in_mb = MBX_0;
813 mcp->timeout = MAILBOX_TOV;
814 rval = ql_mailbox_command(ha, mcp);
815
816 if (rval != QL_SUCCESS) {
817 EL(ha, "failed=%xh\n", rval);
818 } else {
819 /*EMPTY*/
820 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
821 }
822 return (rval);
823 }
824
825 /*
826 * ql_send_lfa
827 * Send a Loop Fabric Address mailbox command.
828 *
829 * Input:
830 * ha: adapter state pointer.
831 * lfa: LFA command structure pointer.
832 *
833 * Returns:
834 * ql local function return status code.
835 *
836 * Context:
837 * Kernel context.
838 */
839 int
840 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
841 {
842 int rval;
843 uint16_t size;
844 dma_mem_t mem_desc;
845 mbx_cmd_t mc = {0};
846 mbx_cmd_t *mcp = &mc;
847
848 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
849
850 /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
851 size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
852
853 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
854 if (rval != QL_SUCCESS) {
855 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
856 return (rval);
857 }
858
859 mcp->mb[0] = MBC_SEND_LFA_COMMAND;
860 mcp->mb[1] = (uint16_t)(size >> 1);
861 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
862 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
863 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
864 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
865 mcp->in_mb = MBX_0;
866 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
867 if (ha->flags & VP_ENABLED) {
868 mcp->mb[9] = ha->vp_index;
869 mcp->out_mb |= MBX_9;
870 }
871 mcp->timeout = MAILBOX_TOV;
872 rval = ql_mailbox_command(ha, mcp);
873
874 ql_free_dma_resource(ha, &mem_desc);
875
876 if (rval != QL_SUCCESS) {
877 EL(ha, "failed, rval = %xh\n", rval);
878 } else {
879 /*EMPTY*/
880 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
881 }
882
883 return (rval);
884 }
885
886 /*
887 * ql_clear_aca
888 * Issue clear ACA mailbox command.
889 *
890 * Input:
891 * ha: adapter state pointer.
892 * tq: target queue pointer.
893 * lun: LUN.
894 *
895 * Returns:
896 * ql local function return status code.
897 *
898 * Context:
899 * Kernel context.
900 */
901 int
902 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
903 {
904 int rval;
905 mbx_cmd_t mc = {0};
906 mbx_cmd_t *mcp = &mc;
907
908 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
909
910 if (CFG_IST(ha, CFG_CTRL_24258081)) {
911 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0);
912 } else {
913 mcp->mb[0] = MBC_CLEAR_ACA;
914 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
915 mcp->mb[1] = tq->loop_id;
916 } else {
917 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
918 }
919 mcp->mb[2] = lun;
920 mcp->out_mb = MBX_2|MBX_1|MBX_0;
921 mcp->in_mb = MBX_0;
922 mcp->timeout = MAILBOX_TOV;
923 rval = ql_mailbox_command(ha, mcp);
924 }
925
926 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
927
928 if (rval != QL_SUCCESS) {
929 EL(ha, "failed, rval = %xh\n", rval);
930 } else {
931 /*EMPTY*/
932 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
933 }
934
935 return (rval);
936 }
937
938 /*
939 * ql_target_reset
940 * Issue target reset mailbox command.
941 *
942 * Input:
943 * ha: adapter state pointer.
944 * tq: target queue pointer.
945 * delay: seconds.
946 *
947 * Returns:
948 * ql local function return status code.
949 *
950 * Context:
951 * Kernel context.
952 */
953 int
954 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
955 {
956 ql_link_t *link;
957 uint16_t index;
958 int rval;
959 mbx_cmd_t mc = {0};
960 mbx_cmd_t *mcp = &mc;
961
962 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
963
964 if (CFG_IST(ha, CFG_CTRL_24258081)) {
965 /* queue = NULL, all targets. */
966 if (tq == NULL) {
967 for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
968 index++) {
969 for (link = ha->dev[index].first; link !=
970 NULL; link = link->next) {
971 tq = link->base_address;
972 if (!VALID_DEVICE_ID(ha,
973 tq->loop_id)) {
974 continue;
975 }
976
977 if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
978 rval = ql_task_mgmt_iocb(ha,
979 tq, 0, CF_DO_NOT_SEND |
980 CF_TARGET_RESET, delay);
981 } else {
982 rval = ql_task_mgmt_iocb(ha,
983 tq, 0, CF_TARGET_RESET,
984 delay);
1015 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1016 mcp->mb[1] = tq->loop_id;
1017 } else {
1018 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1019 }
1020 mcp->mb[2] = delay;
1021 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1022 }
1023 mcp->in_mb = MBX_0;
1024 mcp->timeout = MAILBOX_TOV;
1025 rval = ql_mailbox_command(ha, mcp);
1026 }
1027
1028 tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1029 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1030
1031 if (rval != QL_SUCCESS) {
1032 EL(ha, "failed, rval = %xh\n", rval);
1033 } else {
1034 /*EMPTY*/
1035 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1036 }
1037
1038 return (rval);
1039 }
1040
1041 /*
1042 * ql_abort_target
1043 * Issue abort target mailbox command.
1044 *
1045 * Input:
1046 * ha: adapter state pointer.
1047 * tq: target queue pointer.
1048 * delay: in seconds.
1049 *
1050 * Returns:
1051 * ql local function return status code.
1052 *
1053 * Context:
1054 * Kernel context.
1055 */
1056 int
1057 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1058 {
1059 int rval;
1060 mbx_cmd_t mc = {0};
1061 mbx_cmd_t *mcp = &mc;
1062
1063 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1064
1065 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1066 rval = ql_task_mgmt_iocb(ha, tq, 0,
1067 CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1068 } else {
1069 mcp->mb[0] = MBC_ABORT_TARGET;
1070 /* Don't send Task Mgt */
1071 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1072 mcp->mb[1] = tq->loop_id;
1073 mcp->mb[10] = BIT_0;
1074 mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1075 } else {
1076 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1077 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1078 }
1079 mcp->mb[2] = delay;
1080 mcp->in_mb = MBX_0;
1081 mcp->timeout = MAILBOX_TOV;
1082 rval = ql_mailbox_command(ha, mcp);
1083 }
1084
1085 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1086
1087 if (rval != QL_SUCCESS) {
1088 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1089 } else {
1090 /*EMPTY*/
1091 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1092 }
1093 return (rval);
1094 }
1095
1096 /*
1097 * ql_lun_reset
1098 * Issue LUN reset task management mailbox command.
1099 *
1100 * Input:
1101 * ha: adapter state pointer.
1102 * tq: target queue pointer.
1103 * lun: LUN.
1104 *
1105 * Returns:
1106 * ql local function return status code.
1107 *
1108 * Context:
1109 * Kernel context.
1110 */
1111 int
1112 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1113 {
1114 int rval;
1115 mbx_cmd_t mc = {0};
1116 mbx_cmd_t *mcp = &mc;
1117
1118 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1119
1120 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1121 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0);
1122 } else {
1123 mcp->mb[0] = MBC_LUN_RESET;
1124 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1125 mcp->mb[1] = tq->loop_id;
1126 } else {
1127 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1128 }
1129 mcp->mb[2] = lun;
1130 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1131 mcp->in_mb = MBX_0;
1132 mcp->timeout = MAILBOX_TOV;
1133 rval = ql_mailbox_command(ha, mcp);
1134 }
1135
1136 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1137
1138 if (rval != QL_SUCCESS) {
1139 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1140 } else {
1141 /*EMPTY*/
1142 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1143 }
1144 return (rval);
1145 }
1146
1147 /*
1148 * ql_clear_task_set
1149 * Issue clear task set mailbox command.
1150 *
1151 * Input:
1152 * ha: adapter state pointer.
1153 * tq: target queue pointer.
1154 * lun: LUN.
1155 *
1156 * Returns:
1157 * ql local function return status code.
1158 *
1159 * Context:
1160 * Kernel context.
1161 */
1162 int
1163 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1164 {
1165 int rval;
1166 mbx_cmd_t mc = {0};
1167 mbx_cmd_t *mcp = &mc;
1168
1169 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1170
1171 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1172 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0);
1173 } else {
1174 mcp->mb[0] = MBC_CLEAR_TASK_SET;
1175 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1176 mcp->mb[1] = tq->loop_id;
1177 } else {
1178 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1179 }
1180 mcp->mb[2] = lun;
1181 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1182 mcp->in_mb = MBX_0;
1183 mcp->timeout = MAILBOX_TOV;
1184 rval = ql_mailbox_command(ha, mcp);
1185 }
1186
1187 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1188
1189 if (rval != QL_SUCCESS) {
1190 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1191 } else {
1192 /*EMPTY*/
1193 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1194 }
1195
1196 return (rval);
1197 }
1198
1199 /*
1200 * ql_abort_task_set
1201 * Issue abort task set mailbox command.
1202 *
1203 * Input:
1204 * ha: adapter state pointer.
1205 * tq: target queue pointer.
1206 * lun: LUN.
1207 *
1208 * Returns:
1209 * ql local function return status code.
1210 *
1211 * Context:
1212 * Kernel context.
1213 */
1214 int
1215 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1216 {
1217 int rval;
1218 mbx_cmd_t mc = {0};
1219 mbx_cmd_t *mcp = &mc;
1220
1221 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1222
1223 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1224 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0);
1225 } else {
1226 mcp->mb[0] = MBC_ABORT_TASK_SET;
1227 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1228 mcp->mb[1] = tq->loop_id;
1229 } else {
1230 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1231 }
1232 mcp->mb[2] = lun;
1233 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1234 mcp->in_mb = MBX_0;
1235 mcp->timeout = MAILBOX_TOV;
1236 rval = ql_mailbox_command(ha, mcp);
1237 }
1238
1239 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1240
1241 if (rval != QL_SUCCESS) {
1242 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1243 } else {
1244 /*EMPTY*/
1245 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1246 }
1247
1248 return (rval);
1249 }
1250
1251 /*
1252 * ql_task_mgmt_iocb
1253 * Function issues task management IOCB.
1254 *
1255 * Input:
1256 * ha: adapter state pointer.
1257 * tq: target queue pointer.
1258 * lun: LUN.
1259 * flags: control flags.
1260 * delay: seconds.
1261 *
1262 * Returns:
1263 * ql local function return status code.
1264 *
1265 * Context:
1266 * Kernel context
1267 */
1268 static int
1269 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun,
1270 uint32_t flags, uint16_t delay)
1271 {
1272 ql_mbx_iocb_t *pkt;
1273 int rval;
1274 uint32_t pkt_size;
1275
1276 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1277
1278 pkt_size = sizeof (ql_mbx_iocb_t);
1279 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1280 if (pkt == NULL) {
1281 EL(ha, "failed, kmem_zalloc\n");
1282 return (QL_MEMORY_ALLOC_FAILED);
1283 }
1284
1285 pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1286 pkt->mgmt.entry_count = 1;
1287
1288 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1289 pkt->mgmt.delay = (uint16_t)LE_16(delay);
1290 pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1291 pkt->mgmt.fcp_lun[2] = LSB(lun);
1292 pkt->mgmt.fcp_lun[3] = MSB(lun);
1293 pkt->mgmt.control_flags = LE_32(flags);
1294 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1295 pkt->mgmt.target_id[1] = tq->d_id.b.area;
1296 pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1297 pkt->mgmt.vp_index = ha->vp_index;
1298
1299 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1300 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1301 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1302 pkt->sts24.entry_status, tq->d_id.b24);
1303 rval = QL_FUNCTION_PARAMETER_ERROR;
1304 }
1305
1306 LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1307
1308 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1309 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1310 pkt->sts24.comp_status, tq->d_id.b24);
1311 rval = QL_FUNCTION_FAILED;
1312 }
1313
1314 kmem_free(pkt, pkt_size);
1315
1316 if (rval != QL_SUCCESS) {
1317 EL(ha, "failed, rval = %xh\n", rval);
1318 } else {
1319 /*EMPTY*/
1320 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1321 }
1322
1323 return (rval);
1324 }
1325
1326 /*
1327 * ql_loop_port_bypass
1328 * Issue loop port bypass mailbox command.
1329 *
1330 * Input:
1331 * ha: adapter state pointer.
1332 * tq: target queue pointer.
1333 *
1334 * Returns:
1335 * ql local function return status code.
1336 *
1337 * Context:
1338 * Kernel context.
1339 */
1340 int
1341 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1342 {
1343 int rval;
1344 mbx_cmd_t mc = {0};
1345 mbx_cmd_t *mcp = &mc;
1346
1347 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1348
1349 mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1350
1351 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1352 mcp->mb[1] = tq->d_id.b.al_pa;
1353 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1354 mcp->mb[1] = tq->loop_id;
1355 } else {
1356 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1357 }
1358
1359 mcp->out_mb = MBX_1|MBX_0;
1360 mcp->in_mb = MBX_0;
1361 mcp->timeout = MAILBOX_TOV;
1362 rval = ql_mailbox_command(ha, mcp);
1363
1364 if (rval != QL_SUCCESS) {
1365 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1366 } else {
1367 /*EMPTY*/
1368 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1369 }
1370
1371 return (rval);
1372 }
1373
1374 /*
1375 * ql_loop_port_enable
1376 * Issue loop port enable mailbox command.
1377 *
1378 * Input:
1379 * ha: adapter state pointer.
1380 * tq: target queue pointer.
1381 *
1382 * Returns:
1383 * ql local function return status code.
1384 *
1385 * Context:
1386 * Kernel context.
1387 */
1388 int
1389 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1390 {
1391 int rval;
1392 mbx_cmd_t mc = {0};
1393 mbx_cmd_t *mcp = &mc;
1394
1395 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1396
1397 mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1398
1399 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1400 mcp->mb[1] = tq->d_id.b.al_pa;
1401 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1402 mcp->mb[1] = tq->loop_id;
1403 } else {
1404 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1405 }
1406 mcp->out_mb = MBX_1|MBX_0;
1407 mcp->in_mb = MBX_0;
1408 mcp->timeout = MAILBOX_TOV;
1409 rval = ql_mailbox_command(ha, mcp);
1410
1411 if (rval != QL_SUCCESS) {
1412 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1413 } else {
1414 /*EMPTY*/
1415 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1416 }
1417
1418 return (rval);
1419 }
1420
1421 /*
1422 * ql_login_lport
1423 * Issue login loop port mailbox command.
1424 *
1425 * Input:
1426 * ha: adapter state pointer.
1427 * tq: target queue pointer.
1428 * loop_id: FC loop id.
1429 * opt: options.
1430 * LLF_NONE, LLF_PLOGI
1431 *
1432 * Returns:
1433 * ql local function return status code.
1434 *
1435 * Context:
1436 * Kernel context.
1437 */
1438 int
1439 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1440 uint16_t opt)
1441 {
1442 int rval;
1443 uint16_t flags;
1444 ql_mbx_data_t mr;
1445 mbx_cmd_t mc = {0};
1446 mbx_cmd_t *mcp = &mc;
1447
1448 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1449 ha->instance, tq->d_id.b24, loop_id);
1450
1451 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1452 flags = CF_CMD_PLOGI;
1453 if ((opt & LLF_PLOGI) == 0) {
1454 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1455 }
1456 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1457 } else {
1458 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1459 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1460 mcp->mb[1] = loop_id;
1461 } else {
1462 mcp->mb[1] = (uint16_t)(loop_id << 8);
1463 }
1464 mcp->mb[2] = opt;
1465 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1466 mcp->in_mb = MBX_0;
1467 mcp->timeout = MAILBOX_TOV;
1468 rval = ql_mailbox_command(ha, mcp);
1469 }
1470
1471 if (rval != QL_SUCCESS) {
1472 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1473 loop_id, rval);
1474 } else {
1475 /*EMPTY*/
1476 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1477 }
1478
1479 return (rval);
1480 }
1481
1482 /*
1483 * ql_login_fport
1484 * Issue login fabric port mailbox command.
1485 *
1486 * Input:
1487 * ha: adapter state pointer.
1488 * tq: target queue pointer.
1489 * loop_id: FC loop id.
1490 * opt: options.
1491 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1492 * mr: pointer for mailbox data.
1493 *
1494 * Returns:
1495 * ql local function return status code.
1496 *
1497 * Context:
1498 * Kernel context.
1499 */
1500 int
1501 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1502 uint16_t opt, ql_mbx_data_t *mr)
1503 {
1504 int rval;
1505 uint16_t flags;
1506 mbx_cmd_t mc = {0};
1507 mbx_cmd_t *mcp = &mc;
1508
1509 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1510 ha->instance, tq->d_id.b24, loop_id);
1511
1512 if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1513 opt = (uint16_t)(opt | LFF_NO_PRLI);
1514 }
1515
1516 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1517 flags = CF_CMD_PLOGI;
1518 if (opt & LFF_NO_PLOGI) {
1519 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1520 }
1521 if (opt & LFF_NO_PRLI) {
1522 flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1523 }
1524 rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1525 } else {
1526 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1527 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1528 mcp->mb[1] = loop_id;
1529 mcp->mb[10] = opt;
1530 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1531 } else {
1532 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1533 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1534 }
1535 mcp->mb[2] = MSW(tq->d_id.b24);
1536 mcp->mb[3] = LSW(tq->d_id.b24);
1537 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1538 mcp->timeout = MAILBOX_TOV;
1539 rval = ql_mailbox_command(ha, mcp);
1540
1541 /* Return mailbox data. */
1542 if (mr != NULL) {
1543 mr->mb[0] = mcp->mb[0];
1544 mr->mb[1] = mcp->mb[1];
1545 mr->mb[2] = mcp->mb[2];
1546 mr->mb[6] = mcp->mb[6];
1547 mr->mb[7] = mcp->mb[7];
1548 }
1549 }
1550
1551 if (rval != QL_SUCCESS) {
1552 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1553 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1554 mr->mb[2]);
1555 } else {
1556 /*EMPTY*/
1557 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1558 }
1559
1560 return (rval);
1561 }
1562
1563 /*
1564 * ql_logout_fabric_port
1565 * Issue logout fabric port mailbox command.
1566 *
1567 * Input:
1568 * ha: adapter state pointer.
1569 * tq: target queue pointer.
1570 *
1571 * Returns:
1572 * ql local function return status code.
1573 *
1574 * Context:
1575 * Kernel context.
1576 */
1577 int
1578 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1579 {
1580 int rval;
1581 uint16_t flag;
1582 ql_mbx_data_t mr;
1583 mbx_cmd_t mc = {0};
1584 mbx_cmd_t *mcp = &mc;
1585
1586 QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n",
1587 ha->instance, tq->loop_id, tq->d_id.b24);
1588
1589 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1590 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1591 CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE :
1592 CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1593 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1594 } else {
1595 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0);
1596 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1597 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1598 mcp->mb[1] = tq->loop_id;
1599 mcp->mb[10] = flag;
1600 mcp->out_mb = MBX_10|MBX_1|MBX_0;
1601 } else {
1602 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1603 mcp->out_mb = MBX_1|MBX_0;
1604 }
1605 mcp->in_mb = MBX_0;
1606 mcp->timeout = MAILBOX_TOV;
1607 rval = ql_mailbox_command(ha, mcp);
1608 }
1609
1610 if (rval != QL_SUCCESS) {
1611 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1612 tq->d_id.b24, tq->loop_id);
1613 } else {
1614 /*EMPTY*/
1615 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1616 }
1617
1618 return (rval);
1619 }
1620
1621 /*
1622 * ql_log_iocb
1623 * Function issues login/logout IOCB.
1624 *
1625 * Input:
1626 * ha: adapter state pointer.
1627 * tq: target queue pointer.
1628 * loop_id: FC Loop ID.
1629 * flags: control flags.
1630 * mr: pointer for mailbox data.
1631 *
1632 * Returns:
1633 * ql local function return status code.
1634 *
1635 * Context:
1636 * Kernel context.
1637 */
1638 int
1639 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1640 uint16_t flags, ql_mbx_data_t *mr)
1641 {
1642 ql_mbx_iocb_t *pkt;
1643 int rval;
1644 uint32_t pkt_size;
1645
1646 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1647
1648 pkt_size = sizeof (ql_mbx_iocb_t);
1649 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1650 if (pkt == NULL) {
1651 EL(ha, "failed, kmem_zalloc\n");
1652 return (QL_MEMORY_ALLOC_FAILED);
1653 }
1654
1655 pkt->log.entry_type = LOG_TYPE;
1656 pkt->log.entry_count = 1;
1657 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1658 pkt->log.control_flags = (uint16_t)LE_16(flags);
1659 pkt->log.port_id[0] = tq->d_id.b.al_pa;
1660 pkt->log.port_id[1] = tq->d_id.b.area;
1661 pkt->log.port_id[2] = tq->d_id.b.domain;
1662 pkt->log.vp_index = ha->vp_index;
1663
1664 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1665 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1666 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1751 mr->mb[0] = MBS_PORT_ID_USED;
1752 mr->mb[1] = LSW(pkt->log.io_param[1]);
1753 break;
1754 case CS0_N_PORT_HANDLE_USED:
1755 mr->mb[0] = MBS_LOOP_ID_USED;
1756 mr->mb[1] = MSW(pkt->log.io_param[1]);
1757 mr->mb[2] = LSW(pkt->log.io_param[1]);
1758 break;
1759 case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1760 mr->mb[0] = MBS_ALL_IDS_IN_USE;
1761 break;
1762 case CS0_CMD_PARAMETER_ERROR:
1763 default:
1764 EL(ha, "pkt->log iop[0]=%xh\n",
1765 pkt->log.io_param[0]);
1766 mr->mb[0] =
1767 MBS_COMMAND_PARAMETER_ERROR;
1768 break;
1769 }
1770 } else {
1771 QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1772 ha->instance, pkt->log.status);
1773
1774 mr->mb[0] = MBS_COMMAND_COMPLETE;
1775 mr->mb[1] = (uint16_t)
1776 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1777 if (pkt->log.io_param[0] & BIT_8) {
1778 mr->mb[1] = (uint16_t)
1779 (mr->mb[1] | BIT_1);
1780 }
1781 }
1782 rval = mr->mb[0];
1783 }
1784
1785 }
1786
1787 kmem_free(pkt, pkt_size);
1788
1789 if (rval != QL_SUCCESS) {
1790 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1791 } else {
1792 /*EMPTY*/
1793 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1794 }
1795
1796 return (rval);
1797 }
1798
1799 /*
1800 * ql_get_port_database
1801 * Issue get port database mailbox command
1802 * and copy context to device queue.
1803 *
1804 * Input:
1805 * ha: adapter state pointer.
1806 * tq: target queue pointer.
1807 * opt: options.
1808 * PDF_NONE, PDF_PLOGI, PDF_ADISC
1809 * Returns:
1810 * ql local function return status code.
1811 *
1812 * Context:
1813 * Kernel context.
1814 */
1815 int
1816 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1817 {
1818 int rval;
1819 dma_mem_t mem_desc;
1820 mbx_cmd_t mc = {0};
1821 mbx_cmd_t *mcp = &mc;
1822 port_database_23_t *pd23;
1823
1824 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1825
1826 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1827 if (pd23 == NULL) {
1828 rval = QL_MEMORY_ALLOC_FAILED;
1829 EL(ha, "failed, rval = %xh\n", rval);
1830 return (rval);
1831 }
1832
1833 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1834 PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1835 return (QL_MEMORY_ALLOC_FAILED);
1836 }
1837
1838 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1839 mcp->mb[0] = MBC_GET_PORT_DATABASE;
1840 mcp->mb[1] = tq->loop_id;
1841 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1842 mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1843 mcp->mb[9] = ha->vp_index;
1844 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1845 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1846 MBX_2|MBX_1|MBX_0;
1847 } else {
1848 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1849 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1850 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1851 mcp->mb[1] = tq->loop_id;
1852 mcp->mb[10] = opt;
1853 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1854 MBX_2|MBX_1|MBX_0;
1855 } else {
1856 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1857 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1858 }
1859 }
1860
1861 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1862 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1863 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1864 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1865 mcp->in_mb = MBX_0;
1866 mcp->timeout = MAILBOX_TOV;
1867 rval = ql_mailbox_command(ha, mcp);
1868
1869 if (rval == QL_SUCCESS) {
1870 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1871 }
1872
1873 ql_free_dma_resource(ha, &mem_desc);
1874
1875 if (rval == QL_SUCCESS) {
1876 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1877 port_database_24_t *pd24 = (port_database_24_t *)pd23;
1878
1879 tq->master_state = pd24->current_login_state;
1880 tq->slave_state = pd24->last_stable_login_state;
1881 if (PD_PORT_LOGIN(tq)) {
1882 /* Names are big endian. */
1883 bcopy((void *)&pd24->port_name[0],
1884 (void *)&tq->port_name[0], 8);
1885 bcopy((void *)&pd24->node_name[0],
1886 (void *)&tq->node_name[0], 8);
1887 tq->hard_addr.b.al_pa = pd24->hard_address[2];
1888 tq->hard_addr.b.area = pd24->hard_address[1];
1889 tq->hard_addr.b.domain = pd24->hard_address[0];
1890 tq->class3_rcv_data_size =
1891 pd24->receive_data_size;
1892 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1893 tq->prli_svc_param_word_0 =
1894 pd24->PRLI_service_parameter_word_0;
1895 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1896 tq->prli_svc_param_word_3 =
1948 rval = QL_NOT_LOGGED_IN;
1949 } else {
1950 tq->flags = tq->prli_svc_param_word_3 &
1951 PRLI_W3_TARGET_FUNCTION ?
1952 tq->flags & ~TQF_INITIATOR_DEVICE :
1953 tq->flags | TQF_INITIATOR_DEVICE;
1954
1955 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
1956 tq->flags = tq->prli_svc_param_word_3 &
1957 PRLI_W3_RETRY ?
1958 tq->flags | TQF_TAPE_DEVICE :
1959 tq->flags & ~TQF_TAPE_DEVICE;
1960 } else {
1961 tq->flags &= ~TQF_TAPE_DEVICE;
1962 }
1963 }
1964 }
1965
1966 kmem_free(pd23, PORT_DATABASE_SIZE);
1967
1968 if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
1969 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1970 tq->loop_id, rval);
1971 } else {
1972 /*EMPTY*/
1973 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1974 }
1975
1976 return (rval);
1977 }
1978
1979 /*
1980 * ql_get_loop_position_map
1981 * Issue get loop position map mailbox command.
1982 *
1983 * Input:
1984 * ha: adapter state pointer.
1985 * size: size of data buffer.
1986 * bufp: data pointer for DMA data.
1987 *
1988 * Returns:
1989 * ql local function return status code.
1990 *
1991 * Context:
1992 * Kernel context.
1993 */
1994 int
1995 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
1996 {
1997 int rval;
1998 dma_mem_t mem_desc;
1999 mbx_cmd_t mc = {0};
2000 mbx_cmd_t *mcp = &mc;
2001
2002 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2003
2004 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2005 (uint32_t)size)) != QL_SUCCESS) {
2006 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2007 return (QL_MEMORY_ALLOC_FAILED);
2008 }
2009
2010 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2011 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2012 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2013 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2014 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2015 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2016 mcp->in_mb = MBX_1|MBX_0;
2017 mcp->timeout = MAILBOX_TOV;
2018 rval = ql_mailbox_command(ha, mcp);
2019
2020 if (rval == QL_SUCCESS) {
2021 ql_get_mbox_dma_data(&mem_desc, bufp);
2022 }
2023
2024 ql_free_dma_resource(ha, &mem_desc);
2025
2026 if (rval != QL_SUCCESS) {
2027 EL(ha, "failed=%xh\n", rval);
2028 } else {
2029 /*EMPTY*/
2030 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2031 }
2032
2033 return (rval);
2034 }
2035
2036 /*
2037 * ql_set_rnid_params
2038 * Issue set RNID parameters mailbox command.
2039 *
2040 * Input:
2041 * ha: adapter state pointer.
2042 * size: size of data buffer.
2043 * bufp: data pointer for DMA data.
2044 *
2045 * Returns:
2046 * ql local function return status code.
2047 *
2048 * Context:
2049 * Kernel context.
2050 */
2051 int
2052 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2053 {
2054 int rval;
2055 dma_mem_t mem_desc;
2056 mbx_cmd_t mc = {0};
2057 mbx_cmd_t *mcp = &mc;
2058
2059 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2060
2061 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2062 (uint32_t)size)) != QL_SUCCESS) {
2063 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2064 return (rval);
2065 }
2066
2067 mcp->mb[0] = MBC_SET_PARAMETERS;
2068 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2069 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2070 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2071 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2072 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2073 mcp->in_mb = MBX_0;
2074 mcp->timeout = MAILBOX_TOV;
2075 rval = ql_mailbox_command(ha, mcp);
2076
2077 ql_free_dma_resource(ha, &mem_desc);
2078
2079 if (rval != QL_SUCCESS) {
2080 EL(ha, "failed, rval = %xh\n", rval);
2081 } else {
2082 /*EMPTY*/
2083 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2084 }
2085
2086 return (rval);
2087 }
2088
2089 /*
2090 * ql_send_rnid_els
2091 * Issue a send node identfication data mailbox command.
2092 *
2093 * Input:
2094 * ha: adapter state pointer.
2095 * loop_id: FC loop id.
2096 * opt: options.
2097 * size: size of data buffer.
2098 * bufp: data pointer for DMA data.
2099 *
2100 * Returns:
2101 * ql local function return status code.
2102 *
2103 * Context:
2104 * Kernel context.
2105 */
2106 int
2107 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2108 size_t size, caddr_t bufp)
2109 {
2110 int rval;
2111 dma_mem_t mem_desc;
2112 mbx_cmd_t mc = {0};
2113 mbx_cmd_t *mcp = &mc;
2114
2115 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2116
2117 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2118 (uint32_t)size)) != QL_SUCCESS) {
2119 return (QL_MEMORY_ALLOC_FAILED);
2120 }
2121
2122 mcp->mb[0] = MBC_SEND_RNID_ELS;
2123 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2124 mcp->mb[1] = loop_id;
2125 mcp->mb[9] = ha->vp_index;
2126 mcp->mb[10] = opt;
2127 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2128 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2129 mcp->mb[1] = loop_id;
2130 mcp->mb[10] = opt;
2131 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2132 } else {
2133 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2134 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2135 }
2136 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2137 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2138 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2139 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2140 mcp->in_mb = MBX_0;
2141 mcp->timeout = MAILBOX_TOV;
2142 rval = ql_mailbox_command(ha, mcp);
2143
2144 if (rval == QL_SUCCESS) {
2145 ql_get_mbox_dma_data(&mem_desc, bufp);
2146 }
2147
2148 ql_free_dma_resource(ha, &mem_desc);
2149
2150 if (rval != QL_SUCCESS) {
2151 EL(ha, "failed, rval = %xh\n", rval);
2152 } else {
2153 /*EMPTY*/
2154 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2155 }
2156
2157 return (rval);
2158 }
2159
2160 /*
2161 * ql_get_rnid_params
2162 * Issue get RNID parameters mailbox command.
2163 *
2164 * Input:
2165 * ha: adapter state pointer.
2166 * size: size of data buffer.
2167 * bufp: data pointer for DMA data.
2168 *
2169 * Returns:
2170 * ql local function return status code.
2171 *
2172 * Context:
2173 * Kernel context.
2174 */
2175 int
2176 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2177 {
2178 int rval;
2179 dma_mem_t mem_desc;
2180 mbx_cmd_t mc = {0};
2181 mbx_cmd_t *mcp = &mc;
2182
2183 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2184
2185 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2186 (uint32_t)size)) != QL_SUCCESS) {
2187 return (QL_MEMORY_ALLOC_FAILED);
2188 }
2189
2190 mcp->mb[0] = MBC_GET_PARAMETERS;
2191 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2192 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2193 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2194 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2195 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2196 mcp->in_mb = MBX_0;
2197 mcp->timeout = MAILBOX_TOV;
2198 rval = ql_mailbox_command(ha, mcp);
2199
2200 if (rval == QL_SUCCESS) {
2201 ql_get_mbox_dma_data(&mem_desc, bufp);
2202 }
2203
2204 ql_free_dma_resource(ha, &mem_desc);
2205
2206 if (rval != QL_SUCCESS) {
2207 EL(ha, "failed=%xh\n", rval);
2208 } else {
2209 /*EMPTY*/
2210 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2211 }
2212
2213 return (rval);
2214 }
2215
2216 /*
2217 * ql_get_link_status
2218 * Issue get link status mailbox command.
2219 *
2220 * Input:
2221 * ha: adapter state pointer.
2222 * loop_id: FC loop id or n_port_hdl.
2223 * size: size of data buffer.
2224 * bufp: data pointer for DMA data.
2225 * port_no: port number to query.
2226 *
2227 * Returns:
2228 * ql local function return status code.
2229 *
2230 * Context:
2231 * Kernel context.
2232 */
2233 int
2234 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2235 caddr_t bufp, uint8_t port_no)
2236 {
2237 dma_mem_t mem_desc;
2238 mbx_cmd_t mc = {0};
2239 mbx_cmd_t *mcp = &mc;
2240 int rval = QL_SUCCESS;
2241 int retry = 0;
2242
2243 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2244
2245 do {
2246 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2247 (uint32_t)size)) != QL_SUCCESS) {
2248 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2249 return (QL_MEMORY_ALLOC_FAILED);
2250 }
2251
2252 mcp->mb[0] = MBC_GET_LINK_STATUS;
2253 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2254 if (loop_id == ha->loop_id) {
2255 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2256 mcp->mb[8] = (uint16_t)(size >> 2);
2257 mcp->out_mb = MBX_10|MBX_8;
2258 } else {
2259 mcp->mb[1] = loop_id;
2260 mcp->mb[4] = port_no;
2261 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2262 mcp->out_mb = MBX_10|MBX_4;
2263 }
2264 } else {
2265 if (retry) {
2266 port_no = (uint8_t)(port_no | BIT_3);
2267 }
2268 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2269 mcp->mb[1] = loop_id;
2270 mcp->mb[10] = port_no;
2271 mcp->out_mb = MBX_10;
2272 } else {
2273 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2289 ql_get_mbox_dma_data(&mem_desc, bufp);
2290 }
2291
2292 ql_free_dma_resource(ha, &mem_desc);
2293
2294 if (rval != QL_SUCCESS) {
2295 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2296 }
2297
2298 /*
2299 * Some of the devices want d_id in the payload,
2300 * strictly as per standard. Let's retry.
2301 */
2302
2303 } while (rval == QL_COMMAND_ERROR && !retry++);
2304
2305 if (rval != QL_SUCCESS) {
2306 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2307 } else {
2308 /*EMPTY*/
2309 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2310 }
2311
2312 return (rval);
2313 }
2314
2315 /*
2316 * ql_get_status_counts
2317 * Issue get adapter link status counts mailbox command.
2318 *
2319 * Input:
2320 * ha: adapter state pointer.
2321 * loop_id: FC loop id or n_port_hdl.
2322 * size: size of data buffer.
2323 * bufp: data pointer for DMA data.
2324 * port_no: port number to query.
2325 *
2326 * Returns:
2327 * ql local function return status code.
2328 *
2329 * Context:
2330 * Kernel context.
2331 */
2332 int
2333 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2334 caddr_t bufp, uint8_t port_no)
2335 {
2336 dma_mem_t mem_desc;
2337 mbx_cmd_t mc = {0};
2338 mbx_cmd_t *mcp = &mc;
2339 int rval = QL_SUCCESS;
2340
2341 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2342
2343 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2344 (uint32_t)size)) != QL_SUCCESS) {
2345 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2346 return (QL_MEMORY_ALLOC_FAILED);
2347 }
2348
2349 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2350 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2351 mcp->mb[8] = (uint16_t)(size / 4);
2352 mcp->out_mb = MBX_10|MBX_8;
2353 } else {
2354 mcp->mb[0] = MBC_GET_LINK_STATUS;
2355
2356 /* allows reporting when link is down */
2357 if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2358 port_no = (uint8_t)(port_no | BIT_6);
2359 }
2360
2361 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2362 mcp->mb[1] = loop_id;
2363 mcp->mb[10] = port_no;
2364 mcp->out_mb = MBX_10|MBX_1;
2365 } else {
2366 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2367 port_no);
2368 mcp->out_mb = MBX_1;
2369 }
2370 }
2371 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2372 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2373 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2374 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2375 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2376 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2377 mcp->timeout = MAILBOX_TOV;
2378 rval = ql_mailbox_command(ha, mcp);
2379
2380 if (rval == QL_SUCCESS) {
2381 ql_get_mbox_dma_data(&mem_desc, bufp);
2382 }
2383
2384 ql_free_dma_resource(ha, &mem_desc);
2385
2386 if (rval != QL_SUCCESS) {
2387 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2388 mcp->mb[1], mcp->mb[2]);
2389 } else {
2390 /*EMPTY*/
2391 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2392 }
2393
2394 return (rval);
2395 }
2396
2397 /*
2398 * ql_reset_link_status
2399 * Issue Reset Link Error Status mailbox command
2400 *
2401 * Input:
2402 * ha: adapter state pointer.
2403 *
2404 * Returns:
2405 * ql local function return status code.
2406 *
2407 * Context:
2408 * Kernel context.
2409 */
2410 int
2411 ql_reset_link_status(ql_adapter_state_t *ha)
2412 {
2413 int rval;
2414 mbx_cmd_t mc = {0};
2415 mbx_cmd_t *mcp = &mc;
2416
2417 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2418
2419 mcp->mb[0] = MBC_RESET_LINK_STATUS;
2420 mcp->out_mb = MBX_0;
2421 mcp->in_mb = MBX_0;
2422 mcp->timeout = MAILBOX_TOV;
2423 rval = ql_mailbox_command(ha, mcp);
2424
2425 if (rval != QL_SUCCESS) {
2426 EL(ha, "failed=%xh\n", rval);
2427 } else {
2428 /*EMPTY*/
2429 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2430 }
2431
2432 return (rval);
2433 }
2434
2435 /*
2436 * ql_loop_reset
2437 * Issue loop reset.
2438 *
2439 * Input:
2440 * ha: adapter state pointer.
2441 *
2442 * Returns:
2443 * ql local function return status code.
2444 *
2445 * Context:
2446 * Kernel context.
2447 */
2448 int
2449 ql_loop_reset(ql_adapter_state_t *ha)
2450 {
2451 int rval;
2452
2453 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2454
2455 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2456 rval = ql_lip_reset(ha, 0xff);
2457 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2458 rval = ql_full_login_lip(ha);
2459 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2460 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2461 } else {
2462 rval = ql_initiate_lip(ha);
2463 }
2464
2465 if (rval != QL_SUCCESS) {
2466 EL(ha, "failed, rval = %xh\n", rval);
2467 } else {
2468 /*EMPTY*/
2469 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2470 }
2471
2472 return (rval);
2473 }
2474
2475 /*
2476 * ql_initiate_lip
2477 * Initiate LIP mailbox command.
2478 *
2479 * Input:
2480 * ha: adapter state pointer.
2481 *
2482 * Returns:
2483 * ql local function return status code.
2484 *
2485 * Context:
2486 * Kernel context.
2487 */
2488 int
2489 ql_initiate_lip(ql_adapter_state_t *ha)
2490 {
2491 int rval;
2492 mbx_cmd_t mc = {0};
2493 mbx_cmd_t *mcp = &mc;
2494
2495 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2496
2497 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2498 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2499 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2500 BIT_1 : BIT_4);
2501 mcp->mb[3] = ha->loop_reset_delay;
2502 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2503 } else {
2504 mcp->mb[0] = MBC_INITIATE_LIP;
2505 mcp->out_mb = MBX_0;
2506 }
2507 mcp->in_mb = MBX_0;
2508 mcp->timeout = MAILBOX_TOV;
2509 rval = ql_mailbox_command(ha, mcp);
2510
2511 if (rval != QL_SUCCESS) {
2512 EL(ha, "failed, rval = %xh\n", rval);
2513 } else {
2514 /*EMPTY*/
2515 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2516 }
2517
2518 return (rval);
2519 }
2520
2521 /*
2522 * ql_full_login_lip
2523 * Issue full login LIP mailbox command.
2524 *
2525 * Input:
2526 * ha: adapter state pointer.
2527 *
2528 * Returns:
2529 * ql local function return status code.
2530 *
2531 * Context:
2532 * Kernel context.
2533 */
2534 int
2535 ql_full_login_lip(ql_adapter_state_t *ha)
2536 {
2537 int rval;
2538 mbx_cmd_t mc = {0};
2539 mbx_cmd_t *mcp = &mc;
2540
2541 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2542
2543 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2544 if (CFG_IST(ha, CFG_CTRL_2425)) {
2545 mcp->mb[1] = BIT_3;
2546 } else if (CFG_IST(ha, CFG_CTRL_8081)) {
2547 mcp->mb[1] = BIT_1;
2548 }
2549 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2550 mcp->in_mb = MBX_0;
2551 mcp->timeout = MAILBOX_TOV;
2552 rval = ql_mailbox_command(ha, mcp);
2553
2554 if (rval != QL_SUCCESS) {
2555 EL(ha, "failed, rval = %xh\n", rval);
2556 } else {
2557 /*EMPTY*/
2558 QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2559 }
2560
2561 return (rval);
2562 }
2563
2564 /*
2565 * ql_lip_reset
2566 * Issue lip reset to a port.
2567 *
2568 * Input:
2569 * ha: adapter state pointer.
2570 * loop_id: FC loop id.
2571 *
2572 * Returns:
2573 * ql local function return status code.
2574 *
2575 * Context:
2576 * Kernel context.
2577 */
2578 int
2579 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2580 {
2581 int rval;
2582 mbx_cmd_t mc = {0};
2583 mbx_cmd_t *mcp = &mc;
2584
2585 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2586
2587 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2588 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2589 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2590 BIT_1 : BIT_6);
2591 mcp->mb[3] = ha->loop_reset_delay;
2592 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2593 } else {
2594 mcp->mb[0] = MBC_LIP_RESET;
2595 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2596 mcp->mb[1] = loop_id;
2597 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2598 } else {
2599 mcp->mb[1] = (uint16_t)(loop_id << 8);
2600 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2601 }
2602 mcp->mb[2] = ha->loop_reset_delay;
2603 }
2604 mcp->in_mb = MBX_0;
2605 mcp->timeout = MAILBOX_TOV;
2606 rval = ql_mailbox_command(ha, mcp);
2607
2608 if (rval != QL_SUCCESS) {
2609 EL(ha, "failed, rval = %xh\n", rval);
2610 } else {
2611 /*EMPTY*/
2612 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2613 }
2614
2615 return (rval);
2616 }
2617
2618 /*
2619 * ql_abort_command
2620 * Abort command aborts a specified IOCB.
2621 *
2622 * Input:
2623 * ha: adapter state pointer.
2624 * sp: SRB structure pointer.
2625 *
2626 * Returns:
2627 * ql local function return status code.
2628 *
2629 * Context:
2630 * Kernel context.
2631 */
2632 int
2633 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2634 {
2635 int rval;
2636 mbx_cmd_t mc = {0};
2637 mbx_cmd_t *mcp = &mc;
2638 ql_tgt_t *tq = sp->lun_queue->target_queue;
2639
2640 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2641
2642 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2643 rval = ql_abort_cmd_iocb(ha, sp);
2644 } else {
2645 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2646 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2647 mcp->mb[1] = tq->loop_id;
2648 } else {
2649 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2650 }
2651 mcp->mb[2] = LSW(sp->handle);
2652 mcp->mb[3] = MSW(sp->handle);
2653 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2654 sp->lun_queue->lun_no : 0);
2655 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2656 mcp->in_mb = MBX_0;
2657 mcp->timeout = MAILBOX_TOV;
2658 rval = ql_mailbox_command(ha, mcp);
2659 }
2660
2661 if (rval != QL_SUCCESS) {
2662 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2663 tq->d_id.b24, sp->handle);
2664 } else {
2665 /*EMPTY*/
2666 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2667 }
2668
2669 return (rval);
2670 }
2671
2672 /*
2673 * ql_abort_cmd_iocb
2674 * Function issues abort command IOCB.
2675 *
2676 * Input:
2677 * ha: adapter state pointer.
2678 * sp: SRB structure pointer.
2679 *
2680 * Returns:
2681 * ql local function return status code.
2682 *
2683 * Context:
2684 * Interrupt or Kernel context, no mailbox commands allowed.
2685 */
2686 static int
2687 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2688 {
2689 ql_mbx_iocb_t *pkt;
2690 int rval;
2691 uint32_t pkt_size;
2692 uint16_t comp_status;
2693 ql_tgt_t *tq = sp->lun_queue->target_queue;
2694
2695 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2696
2697 pkt_size = sizeof (ql_mbx_iocb_t);
2698 if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2699 EL(ha, "failed, kmem_zalloc\n");
2700 return (QL_MEMORY_ALLOC_FAILED);
2701 }
2702
2703 pkt->abo.entry_type = ABORT_CMD_TYPE;
2704 pkt->abo.entry_count = 1;
2705 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2706 if (!CFG_IST(ha, CFG_CTRL_8021)) {
2707 pkt->abo.options = AF_NO_ABTS;
2708 }
2709 pkt->abo.cmd_handle = LE_32(sp->handle);
2710 pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2711 pkt->abo.target_id[1] = tq->d_id.b.area;
2712 pkt->abo.target_id[2] = tq->d_id.b.domain;
2713 pkt->abo.vp_index = ha->vp_index;
2714
2715 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2716
2717 if (rval == QL_SUCCESS) {
2718 if ((pkt->abo.entry_status & 0x3c) != 0) {
2719 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2720 pkt->abo.entry_status, tq->d_id.b24);
2721 rval = QL_FUNCTION_PARAMETER_ERROR;
2722 } else {
2723 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2724 if (comp_status != CS_COMPLETE) {
2725 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2726 comp_status, tq->d_id.b24);
2727 rval = QL_FUNCTION_FAILED;
2728 }
2729 }
2730 }
2731
2732 kmem_free(pkt, pkt_size);
2733
2734 if (rval != QL_SUCCESS) {
2735 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2736 } else {
2737 /*EMPTY*/
2738 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2739 }
2740
2741 return (rval);
2742 }
2743
2744 /*
2745 * ql_verify_checksum
2746 * Verify loaded RISC firmware.
2747 *
2748 * Input:
2749 * ha = adapter state pointer.
2750 *
2751 * Returns:
2752 * ql local function return status code.
2753 *
2754 * Context:
2755 * Kernel context.
2756 */
2757 int
2758 ql_verify_checksum(ql_adapter_state_t *ha)
2759 {
2760 int rval;
2761 mbx_cmd_t mc = {0};
2762 mbx_cmd_t *mcp = &mc;
2763
2764 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2765
2766 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2767 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2768 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2769 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2770 } else {
2771 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2772 }
2773 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2774 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2775 mcp->timeout = MAILBOX_TOV;
2776 rval = ql_mailbox_command(ha, mcp);
2777
2778 if (rval != QL_SUCCESS) {
2779 EL(ha, "failed, rval = %xh\n", rval);
2780 } else {
2781 /*EMPTY*/
2782 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2783 }
2784
2785 return (rval);
2786 }
2787
2788 /*
2789 * ql_get_id_list
2790 * Get d_id and loop ID list.
2791 *
2792 * Input:
2793 * ha: adapter state pointer.
2794 * bp: data pointer for DMA data.
2795 * size: size of data buffer.
2796 * mr: pointer for mailbox data.
2797 *
2798 * Returns:
2799 * ql local function return status code.
2800 *
2801 * Context:
2802 * Kernel context.
2803 */
2804 int
2805 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2806 ql_mbx_data_t *mr)
2807 {
2808 int rval;
2809 dma_mem_t mem_desc;
2810 mbx_cmd_t mc = {0};
2811 mbx_cmd_t *mcp = &mc;
2812
2813 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2814
2815 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2816 (uint32_t)size)) != QL_SUCCESS) {
2817 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2818 return (QL_MEMORY_ALLOC_FAILED);
2819 }
2820
2821 mcp->mb[0] = MBC_GET_ID_LIST;
2822 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2823 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2824 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2825 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2826 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2827 mcp->mb[8] = (uint16_t)size;
2828 mcp->mb[9] = ha->vp_index;
2829 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2830 } else {
2831 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2832 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2833 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2834 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2835 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2836 }
2837 mcp->in_mb = MBX_1|MBX_0;
2838 mcp->timeout = MAILBOX_TOV;
2839 rval = ql_mailbox_command(ha, mcp);
2840
2841 if (rval == QL_SUCCESS) {
2842 ql_get_mbox_dma_data(&mem_desc, bp);
2843 }
2844
2845 ql_free_dma_resource(ha, &mem_desc);
2846
2847 /* Return mailbox data. */
2848 if (mr != NULL) {
2849 mr->mb[0] = mcp->mb[0];
2850 mr->mb[1] = mcp->mb[1];
2851 }
2852
2853 if (rval != QL_SUCCESS) {
2854 EL(ha, "failed, rval = %xh\n", rval);
2855 } else {
2856 /*EMPTY*/
2857 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2858 }
2859
2860 return (rval);
2861 }
2862
2863 /*
2864 * ql_wrt_risc_ram
2865 * Load RISC RAM.
2866 *
2867 * Input:
2868 * ha: adapter state pointer.
2869 * risc_address: risc ram word address.
2870 * bp: DMA pointer.
2871 * word_count: 16/32bit word count.
2872 *
2873 * Returns:
2874 * ql local function return status code.
2875 *
2876 * Context:
2877 * Kernel context.
2878 */
2879 int
2880 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2881 uint32_t word_count)
2882 {
2883 int rval;
2884 mbx_cmd_t mc = {0};
2885 mbx_cmd_t *mcp = &mc;
2886
2887 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2888
2889 if (CFG_IST(ha, CFG_CTRL_242581)) {
2890 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2891 mcp->mb[4] = MSW(word_count);
2892 mcp->mb[5] = LSW(word_count);
2893 mcp->mb[6] = MSW(MSD(bp));
2894 mcp->mb[7] = LSW(MSD(bp));
2895 mcp->mb[8] = MSW(risc_address);
2896 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2897 MBX_0;
2898 } else {
2899 mcp->mb[0] = MBC_LOAD_RAM;
2900 mcp->mb[4] = LSW(word_count);
2901 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2902 }
2903 mcp->mb[1] = LSW(risc_address);
2904 mcp->mb[2] = MSW(LSD(bp));
2905 mcp->mb[3] = LSW(LSD(bp));
2906 mcp->in_mb = MBX_0;
2907 mcp->timeout = MAILBOX_TOV;
2908
2909 rval = ql_mailbox_command(ha, mcp);
2910
2911 if (rval != QL_SUCCESS) {
2912 EL(ha, "failed, rval = %xh\n", rval);
2913 } else {
2914 /*EMPTY*/
2915 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2916 }
2917
2918 return (rval);
2919 }
2920
2921 /*
2922 * ql_rd_risc_ram
2923 * Get RISC RAM.
2924 *
2925 * Input:
2926 * ha: adapter state pointer.
2927 * risc_address: risc ram word address.
2928 * bp: direct data pointer.
2929 * word_count: 16/32bit word count.
2930 *
2931 * Returns:
2932 * ql local function return status code.
2933 *
2934 * Context:
2935 * Kernel context.
2936 */
2937 int
2938 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2939 uint32_t word_count)
2940 {
2941 int rval;
2942 mbx_cmd_t mc = {0};
2943 mbx_cmd_t *mcp = &mc;
2944
2945 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2946
2947 if (CFG_IST(ha, CFG_CTRL_242581)) {
2948 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
2949 mcp->mb[1] = LSW(risc_address);
2950 mcp->mb[2] = MSW(LSD(bp));
2951 mcp->mb[3] = LSW(LSD(bp));
2952 mcp->mb[4] = MSW(word_count);
2953 mcp->mb[5] = LSW(word_count);
2954 mcp->mb[6] = MSW(MSD(bp));
2955 mcp->mb[7] = LSW(MSD(bp));
2956 mcp->mb[8] = MSW(risc_address);
2957 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2958 MBX_0;
2959 } else {
2960 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */
2961 mcp->mb[1] = LSW(risc_address);
2962 mcp->mb[2] = MSW(LSD(bp));
2963 mcp->mb[3] = LSW(LSD(bp));
2964 mcp->mb[4] = LSW(word_count);
2965 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2966 }
2967 mcp->in_mb = MBX_0;
2968 mcp->timeout = MAILBOX_TOV;
2969 rval = ql_mailbox_command(ha, mcp);
2970
2971 if (rval != QL_SUCCESS) {
2972 EL(ha, "failed, rval = %xh\n", rval);
2973 } else {
2974 /*EMPTY*/
2975 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2976 }
2977
2978 return (rval);
2979 }
2980
2981 /*
2982 * ql_wrt_risc_ram_word
2983 * Write RISC RAM word.
2984 *
2985 * Input:
2986 * ha: adapter state pointer.
2987 * risc_address: risc ram word address.
2988 * data: data.
2989 *
2990 * Returns:
2991 * ql local function return status code.
2992 *
2993 * Context:
2994 * Kernel context.
2995 */
2996 int
2997 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
2998 uint32_t data)
2999 {
3000 int rval;
3001 mbx_cmd_t mc = {0};
3002 mbx_cmd_t *mcp = &mc;
3003
3004 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3005
3006 mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3007 mcp->mb[1] = LSW(risc_address);
3008 mcp->mb[2] = LSW(data);
3009 mcp->mb[3] = MSW(data);
3010 mcp->mb[8] = MSW(risc_address);
3011 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3012 mcp->in_mb = MBX_0;
3013 mcp->timeout = MAILBOX_TOV;
3014
3015 rval = ql_mailbox_command(ha, mcp);
3016
3017 if (rval != QL_SUCCESS) {
3018 EL(ha, "failed, rval = %xh\n", rval);
3019 } else {
3020 /*EMPTY*/
3021 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3022 }
3023
3024 return (rval);
3025 }
3026
3027 /*
3028 * ql_rd_risc_ram_word
3029 * Read RISC RAM word.
3030 *
3031 * Input:
3032 * ha: adapter state pointer.
3033 * risc_address: risc ram word address.
3034 * data: data pointer.
3035 *
3036 * Returns:
3037 * ql local function return status code.
3038 *
3039 * Context:
3040 * Kernel context.
3041 */
3042 int
3043 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3044 uint32_t *data)
3045 {
3046 int rval;
3047 mbx_cmd_t mc = {0};
3048 mbx_cmd_t *mcp = &mc;
3049
3050 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3051
3052 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3053 mcp->mb[1] = LSW(risc_address);
3054 mcp->mb[8] = MSW(risc_address);
3055 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3056 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3057 mcp->timeout = MAILBOX_TOV;
3058
3059 rval = ql_mailbox_command(ha, mcp);
3060
3061 if (rval != QL_SUCCESS) {
3062 EL(ha, "failed, rval = %xh\n", rval);
3063 } else {
3064 *data = mcp->mb[2];
3065 if (CFG_IST(ha, CFG_CTRL_24258081)) {
3066 *data |= mcp->mb[3] << 16;
3067 }
3068 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3069 }
3070
3071 return (rval);
3072 }
3073
3074 /*
3075 * ql_issue_mbx_iocb
3076 * Issue IOCB using mailbox command
3077 *
3078 * Input:
3079 * ha: adapter state pointer.
3080 * bp: buffer pointer.
3081 * size: buffer size.
3082 *
3083 * Returns:
3084 * ql local function return status code.
3085 *
3086 * Context:
3087 * Kernel context.
3088 */
3089 int
3090 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3091 {
3092 int rval;
3093 dma_mem_t mem_desc;
3094 mbx_cmd_t mc = {0};
3095 mbx_cmd_t *mcp = &mc;
3096
3097 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3098
3099 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3100 QL_SUCCESS) {
3101 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3102 return (rval);
3103 }
3104
3105 mcp->mb[0] = MBC_EXECUTE_IOCB;
3106 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3107 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3108 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3109 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3110 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3111 mcp->in_mb = MBX_1|MBX_0;
3112 mcp->timeout = MAILBOX_TOV + 5;
3113 rval = ql_mailbox_command(ha, mcp);
3114
3115 if (rval == QL_SUCCESS) {
3116 ql_get_mbox_dma_data(&mem_desc, bp);
3117 }
3118
3119 ql_free_dma_resource(ha, &mem_desc);
3120
3121 if (rval != QL_SUCCESS) {
3122 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3123 } else {
3124 /*EMPTY*/
3125 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3126 }
3127
3128 return (rval);
3129 }
3130
3131 /*
3132 * ql_mbx_wrap_test
3133 * Mailbox register wrap test.
3134 *
3135 * Input:
3136 * ha: adapter state pointer.
3137 * mr: pointer for in/out mailbox data.
3138 *
3139 * Returns:
3140 * ql local function return status code.
3141 *
3142 * Context:
3143 * Kernel context.
3144 */
3145 int
3146 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3147 {
3148 int rval;
3149 mbx_cmd_t mc = {0};
3150 mbx_cmd_t *mcp = &mc;
3151
3152 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3153
3154 if (mr != NULL) {
3155 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3156 mcp->mb[1] = mr->mb[1];
3157 mcp->mb[2] = mr->mb[2];
3158 mcp->mb[3] = mr->mb[3];
3159 mcp->mb[4] = mr->mb[4];
3160 mcp->mb[5] = mr->mb[5];
3161 mcp->mb[6] = mr->mb[6];
3162 mcp->mb[7] = mr->mb[7];
3163 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3164 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3165 mcp->timeout = MAILBOX_TOV;
3166 rval = ql_mailbox_command(ha, mcp);
3167 if (rval == QL_SUCCESS) {
3168 mr->mb[1] = mcp->mb[1];
3169 mr->mb[2] = mcp->mb[2];
3170 mr->mb[3] = mcp->mb[3];
3171 mr->mb[4] = mcp->mb[4];
3172 mr->mb[5] = mcp->mb[5];
3173 mr->mb[6] = mcp->mb[6];
3174 mr->mb[7] = mcp->mb[7];
3175 }
3176 } else {
3177 rval = QL_FUNCTION_PARAMETER_ERROR;
3178 }
3179
3180 if (rval != QL_SUCCESS) {
3181 EL(ha, "failed=%xh\n", rval);
3182 } else {
3183 /*EMPTY*/
3184 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3185 }
3186
3187 return (rval);
3188 }
3189
3190 /*
3191 * ql_execute_fw
3192 * Start adapter firmware.
3193 *
3194 * Input:
3195 * ha: adapter state pointer.
3196 *
3197 * Returns:
3198 * ql local function return status code.
3199 *
3200 * Context:
3201 * Kernel context.
3202 */
3203 int
3204 ql_execute_fw(ql_adapter_state_t *ha)
3205 {
3206 int rval;
3207 mbx_cmd_t mc = {0};
3208 mbx_cmd_t *mcp = &mc;
3209
3210 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3211
3212 if (CFG_IST(ha, CFG_CTRL_8021)) {
3213 return (QL_SUCCESS);
3214 }
3215
3216 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3217 if (CFG_IST(ha, CFG_CTRL_242581)) {
3218 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3219 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3220 } else {
3221 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3222 }
3223 if (CFG_IST(ha, CFG_LR_SUPPORT)) {
3224 mcp->mb[4] = BIT_0;
3225 }
3226 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3227 mcp->in_mb = MBX_0;
3228 mcp->timeout = MAILBOX_TOV;
3229 rval = ql_mailbox_command(ha, mcp);
3230
3231 if (CFG_IST(ha, CFG_CTRL_2200)) {
3232 rval = QL_SUCCESS;
3233 }
3234
3235 if (rval != QL_SUCCESS) {
3236 EL(ha, "failed=%xh\n", rval);
3237 } else {
3238 /*EMPTY*/
3239 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3240 }
3241
3242 return (rval);
3243 }
3244
3245 /*
3246 * ql_get_firmware_option
3247 * Get Firmware Options Mailbox Command.
3248 *
3249 * Input:
3250 * ha: adapter state pointer.
3251 * mr: pointer for mailbox data.
3252 *
3253 * Returns:
3254 * ql local function return status code.
3255 *
3256 * Context:
3257 * Kernel context.
3258 */
3259 int
3260 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3261 {
3262 int rval;
3263 mbx_cmd_t mc = {0};
3264 mbx_cmd_t *mcp = &mc;
3265
3266 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3267
3268 mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3269 mcp->out_mb = MBX_0;
3270 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3271 mcp->timeout = MAILBOX_TOV;
3272 rval = ql_mailbox_command(ha, mcp);
3273
3274 /* Return mailbox data. */
3275 if (mr != NULL) {
3276 mr->mb[0] = mcp->mb[0];
3277 mr->mb[1] = mcp->mb[1];
3278 mr->mb[2] = mcp->mb[2];
3279 mr->mb[3] = mcp->mb[3];
3280 }
3281
3282 if (rval != QL_SUCCESS) {
3283 EL(ha, "failed=%xh\n", rval);
3284 } else {
3285 /*EMPTY*/
3286 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
3287 }
3288
3289 return (rval);
3290 }
3291
3292 /*
3293 * ql_set_firmware_option
3294 * Set Firmware Options Mailbox Command.
3295 *
3296 * Input:
3297 * ha: adapter state pointer.
3298 * mr: pointer for mailbox data.
3299 *
3300 * Returns:
3301 * ql local function return status code.
3302 *
3303 * Context:
3304 * Kernel context.
3305 */
3306 int
3307 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3308 {
3309 int rval;
3310 mbx_cmd_t mc = {0};
3311 mbx_cmd_t *mcp = &mc;
3312
3313 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3314
3315 if (mr != NULL) {
3316 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3317 mcp->mb[1] = mr->mb[1];
3318 mcp->mb[2] = mr->mb[2];
3319 mcp->mb[3] = mr->mb[3];
3320 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3321 mcp->in_mb = MBX_0;
3322 mcp->timeout = MAILBOX_TOV;
3323 rval = ql_mailbox_command(ha, mcp);
3324 } else {
3325 rval = QL_FUNCTION_PARAMETER_ERROR;
3326 }
3327
3328 if (rval != QL_SUCCESS) {
3329 EL(ha, "failed=%xh\n", rval);
3330 } else {
3331 /*EMPTY*/
3332 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3333 }
3334
3335 return (rval);
3336 }
3337
3338 /*
3339 * ql_init_firmware
3340 * Initialize firmware mailbox command.
3341 *
3342 * Input:
3343 * ha: adapter state pointer.
3344 * ha->init_ctrl_blk = setup for transmit.
3345 *
3346 * Returns:
3347 * ql local function return status code.
3348 *
3349 * Context:
3350 * Kernel context.
3351 */
3352 int
3353 ql_init_firmware(ql_adapter_state_t *ha)
3354 {
3355 int rval;
3356 dma_mem_t mem_desc;
3357 mbx_cmd_t mc = {0};
3358 mbx_cmd_t *mcp = &mc;
3359
3360 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3361
3362 if (CFG_IST(ha, CFG_CTRL_8021)) {
3363 WRT32_IO_REG(ha, req_out, 0);
3364 WRT32_IO_REG(ha, resp_in, 0);
3365 WRT32_IO_REG(ha, resp_out, 0);
3366 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
3367 WRT32_IO_REG(ha, req_in, 0);
3368 WRT32_IO_REG(ha, resp_out, 0);
3369 WRT32_IO_REG(ha, pri_req_in, 0);
3370 WRT32_IO_REG(ha, atio_req_out, 0);
3371 } else {
3372 WRT16_IO_REG(ha, req_in, 0);
3373 WRT16_IO_REG(ha, resp_out, 0);
3374 }
3375
3376 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3377 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3378 QL_SUCCESS) {
3379 EL(ha, "dma setup failed=%xh\n", rval);
3380 return (rval);
3381 }
3382
3383 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3384 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3385
3386 if (CFG_IST(ha, CFG_SBUS_CARD)) {
3387 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2200) ?
3388 0x204c : 0x52);
3389 }
3390
3391 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3392 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3393 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3394 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3395 if (CFG_IST(ha, CFG_CTRL_8081)) {
3396 uint64_t ofst, addr;
3397 ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *)
3398 &ha->init_ctrl_blk.cb24;
3399
3400 mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW;
3401 if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) {
3402 ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb;
3403 addr = mem_desc.cookie.dmac_laddress + ofst;
3404 mcp->mb[10] = MSW(LSD(addr));
3405 mcp->mb[11] = LSW(LSD(addr));
3406 mcp->mb[12] = MSW(MSD(addr));
3407 mcp->mb[13] = LSW(MSD(addr));
3408 mcp->mb[14] = sizeof (ql_ext_icb_8100_t);
3409 mcp->mb[1] = BIT_0;
3410 }
3411 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
3412 MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3413 } else {
3414 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3415 }
3416 mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0;
3417 mcp->timeout = MAILBOX_TOV;
3418 rval = ql_mailbox_command(ha, mcp);
3419
3420 if (rval == QL_SUCCESS) {
3421 ha->sfp_stat = mcp->mb[2];
3422 }
3423 ql_free_dma_resource(ha, &mem_desc);
3424
3425 if (rval != QL_SUCCESS) {
3426 EL(ha, "failed=%xh\n", rval);
3427 } else {
3428 /*EMPTY*/
3429 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3430 }
3431
3432 return (rval);
3433 }
3434
3435 /*
3436 * ql_get_firmware_state
3437 * Get adapter firmware state.
3438 *
3439 * Input:
3440 * ha: adapter state pointer.
3441 * mr: pointer for mailbox data.
3442 *
3443 * Returns:
3444 * ql local function return status code.
3445 *
3446 * Context:
3447 * Kernel context.
3448 */
3449 int
3450 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3451 {
3452 int rval;
3453 mbx_cmd_t mc = {0};
3454 mbx_cmd_t *mcp = &mc;
3455
3456 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3457
3458 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3459 mcp->out_mb = MBX_0;
3460 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3461 mcp->timeout = MAILBOX_TOV;
3462 rval = ql_mailbox_command(ha, mcp);
3463
3464 /* Return mailbox data. */
3465 if (mr != NULL) {
3466 mr->mb[1] = mcp->mb[1];
3467 mr->mb[2] = mcp->mb[2];
3468 mr->mb[3] = mcp->mb[3];
3469 mr->mb[4] = mcp->mb[4];
3470 mr->mb[5] = mcp->mb[5];
3471 }
3472
3473 ha->sfp_stat = mcp->mb[2];
3474
3475 if (rval != QL_SUCCESS) {
3476 EL(ha, "failed=%xh\n", rval);
3477 } else {
3478 /*EMPTY*/
3479 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3480 }
3481
3482 return (rval);
3483 }
3484
3485 /*
3486 * ql_get_adapter_id
3487 * Get adapter ID and topology.
3488 *
3489 * Input:
3490 * ha: adapter state pointer.
3491 * mr: pointer for mailbox data.
3492 *
3493 * Returns:
3494 * ql local function return status code.
3495 *
3496 * Context:
3497 * Kernel context.
3498 */
3499 int
3500 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3501 {
3502 int rval;
3503 mbx_cmd_t mc = {0};
3504 mbx_cmd_t *mcp = &mc;
3505
3506 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3507
3508 mcp->mb[0] = MBC_GET_ID;
3509 if (ha->flags & VP_ENABLED) {
3510 mcp->mb[9] = ha->vp_index;
3511 }
3512 mcp->out_mb = MBX_9|MBX_0;
3513 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|
3514 MBX_3|MBX_2|MBX_1|MBX_0;
3515 mcp->timeout = MAILBOX_TOV;
3516
3517 rval = ql_mailbox_command(ha, mcp);
3518
3519 /* Return mailbox data. */
3520 if (mr != NULL) {
3521 mr->mb[1] = mcp->mb[1];
3522 mr->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
3523 0xffff : mcp->mb[1]);
3524 mr->mb[2] = mcp->mb[2];
3525 mr->mb[3] = mcp->mb[3];
3526 mr->mb[6] = mcp->mb[6];
3527 mr->mb[7] = mcp->mb[7];
3528 mr->mb[8] = mcp->mb[8];
3529 mr->mb[9] = mcp->mb[9];
3530 mr->mb[10] = mcp->mb[10];
3531 mr->mb[11] = mcp->mb[11];
3532 mr->mb[12] = mcp->mb[12];
3533 mr->mb[13] = mcp->mb[13];
3534 }
3535
3536 if (rval != QL_SUCCESS) {
3537 EL(ha, "failed=%xh\n", rval);
3538 } else {
3539 /*EMPTY*/
3540 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3541 }
3542
3543 return (rval);
3544 }
3545
3546 /*
3547 * ql_get_fw_version
3548 * Get firmware version.
3549 *
3550 * Input:
3551 * ha: adapter state pointer.
3552 * mr: pointer for mailbox data.
3553 *
3554 * Returns:
3555 * ql local function return status code.
3556 *
3557 * Context:
3558 * Kernel context.
3559 */
3560 int
3561 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout)
3562 {
3563 int rval;
3564 mbx_cmd_t mc = {0};
3565 mbx_cmd_t *mcp = &mc;
3566
3567 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3568
3569 mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3570 mcp->out_mb = MBX_0;
3571 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_6|MBX_5|
3572 MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3573 mcp->timeout = timeout;
3574 rval = ql_mailbox_command(ha, mcp);
3575
3576 /* Return mailbox data. */
3577 if (mr != NULL) {
3578 mr->mb[1] = mcp->mb[1];
3579 mr->mb[2] = mcp->mb[2];
3580 mr->mb[3] = mcp->mb[3];
3581 mr->mb[4] = mcp->mb[4];
3582 mr->mb[5] = mcp->mb[5];
3583 mr->mb[6] = mcp->mb[6];
3584 mr->mb[8] = mcp->mb[8];
3585 mr->mb[9] = mcp->mb[9];
3586 mr->mb[10] = mcp->mb[10];
3587 mr->mb[11] = mcp->mb[11];
3588 mr->mb[12] = mcp->mb[12];
3589 mr->mb[13] = mcp->mb[13];
3590 }
3591
3592 if (rval != QL_SUCCESS) {
3593 EL(ha, "failed=%xh\n", rval);
3594 } else {
3595 /*EMPTY*/
3596 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3597 }
3598
3599 return (rval);
3600 }
3601
3602 /*
3603 * ql_data_rate
3604 * Issue data rate Mailbox Command.
3605 *
3606 * Input:
3607 * ha: adapter state pointer.
3608 * mr: pointer for mailbox data.
3609 *
3610 * Returns:
3611 * ql local function return status code.
3612 *
3613 * Context:
3614 * Kernel context.
3615 */
3616 int
3617 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3618 {
3619 int rval;
3620 mbx_cmd_t mc = {0};
3621 mbx_cmd_t *mcp = &mc;
3622
3623 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3624
3625 if (mr != NULL) {
3626 mcp->mb[0] = MBC_DATA_RATE;
3627 mcp->mb[1] = mr->mb[1];
3628 mcp->mb[2] = mr->mb[2];
3629 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3630 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3631 mcp->timeout = MAILBOX_TOV;
3632 rval = ql_mailbox_command(ha, mcp);
3633
3634 /* Return mailbox data. */
3635 mr->mb[1] = mcp->mb[1];
3636 mr->mb[2] = mcp->mb[2];
3637 } else {
3638 rval = QL_FUNCTION_PARAMETER_ERROR;
3639 }
3640
3641 ha->sfp_stat = mcp->mb[2];
3642
3643 if (rval != QL_SUCCESS) {
3644 EL(ha, "failed=%xh\n", rval);
3645 } else {
3646 /*EMPTY*/
3647 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3648 }
3649
3650 return (rval);
3651 }
3652
3653 /*
3654 * ql_Diag_Loopback
3655 * Issue Reset Link Status mailbox command
3656 *
3657 * Input:
3658 * ha: adapter state pointer.
3659 * findex: FCF index.
3660 * bp: buffer pointer.
3661 * size: buffer size.
3662 * opt: command options.
3663 * it_cnt: iteration count.
3664 * mr: pointer for mailbox data.
3665 *
3666 * Returns:
3667 * ql local function return status code.
3668 *
3669 * Context:
3670 * Kernel context.
3671 */
3672 int
3673 ql_diag_loopback(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp,
3674 uint32_t size, uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3675 {
3676 int rval;
3677 dma_mem_t mem_desc;
3678 mbx_cmd_t mc = {0};
3679 mbx_cmd_t *mcp = &mc;
3680
3681 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3682
3683 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3684 QL_SUCCESS) {
3685 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3686 return (rval);
3687 }
3688
3689 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3690 mcp->mb[1] = opt;
3691 mcp->mb[2] = findex;
3692 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3693 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3694 mcp->mb[10] = LSW(size);
3695 mcp->mb[11] = MSW(size);
3696 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3697 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3698 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3699 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3700 mcp->mb[18] = LSW(it_cnt);
3701 mcp->mb[19] = MSW(it_cnt);
3702 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3703 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3704 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3705 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3706 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3707 mcp->timeout = it_cnt / 300;
3708 if (mcp->timeout < MAILBOX_TOV) {
3709 mcp->timeout = MAILBOX_TOV;
3710 }
3711 rval = ql_mailbox_command(ha, mcp);
3713 if (rval == QL_SUCCESS) {
3714 ql_get_mbox_dma_data(&mem_desc, bp);
3715 }
3716
3717 ql_free_dma_resource(ha, &mem_desc);
3718
3719 /* Return mailbox data. */
3720 if (mr != NULL) {
3721 mr->mb[0] = mcp->mb[0];
3722 mr->mb[1] = mcp->mb[1];
3723 mr->mb[2] = mcp->mb[2];
3724 mr->mb[3] = mcp->mb[3];
3725 mr->mb[18] = mcp->mb[18];
3726 mr->mb[19] = mcp->mb[19];
3727 }
3728
3729 if (rval != QL_SUCCESS) {
3730 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3731 } else {
3732 /*EMPTY*/
3733 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3734 }
3735
3736 return (rval);
3737 }
3738
3739 /*
3740 * ql_diag_echo
3741 * Issue Diag echo mailbox command. Valid for qla23xx HBA's.
3742 *
3743 * Input:
3744 * ha: adapter state pointer.
3745 * findex: FCF index.
3746 * bp: buffer pointer.
3747 * size: buffer size.
3748 * opt: command options.
3749 * mr: pointer to mailbox status.
3750 *
3751 * Returns:
3752 * ql local function return status code.
3753 *
3754 * Context:
3755 * Kernel context.
3756 */
3757 int
3758 ql_diag_echo(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp,
3759 uint32_t size, uint16_t opt, ql_mbx_data_t *mr)
3760 {
3761 int rval;
3762 dma_mem_t mem_desc;
3763 mbx_cmd_t mc = {0};
3764 mbx_cmd_t *mcp = &mc;
3765
3766 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3767
3768 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3769 QL_SUCCESS) {
3770 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3771 return (rval);
3772 }
3773
3774 mcp->mb[0] = MBC_ECHO;
3775 mcp->mb[1] = opt;
3776 mcp->mb[2] = findex;
3777 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3778 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3779 mcp->mb[10] = LSW(size);
3780 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3781 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3782 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3783 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3784 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3785 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3786 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3787 MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3788 mcp->in_mb = MBX_1|MBX_0;
3789 mcp->timeout = MAILBOX_TOV;
3790 rval = ql_mailbox_command(ha, mcp);
3791
3792 if (rval == QL_SUCCESS) {
3793 ql_get_mbox_dma_data(&mem_desc, bp);
3794 }
3795
3796 ql_free_dma_resource(ha, &mem_desc);
3797
3798 if (mr != NULL) {
3799 mr->mb[0] = mcp->mb[0];
3800 }
3801
3802 if (rval != QL_SUCCESS) {
3803 EL(ha, "failed=%xh, mb1=%xh\n", rval,
3804 mcp->mb[1]);
3805 } else {
3806 /*EMPTY*/
3807 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3808 }
3809
3810 return (rval);
3811 }
3812
3813 /*
3814 * ql_serdes_param
3815 * Set/Get serdes transmit parameters mailbox command.
3816 *
3817 * Input:
3818 * ha: adapter state pointer.
3819 * mr: pointer to mailbox in/out parameters.
3820 *
3821 * Returns:
3822 * ql local function return status code.
3823 *
3824 * Context:
3825 * Kernel context.
3826 */
3827 int
3828 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3829 {
3830 int rval;
3831 mbx_cmd_t mc = {0};
3832 mbx_cmd_t *mcp = &mc;
3833
3834 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3835
3836 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
3837 mcp->mb[1] = mr->mb[1];
3838 mcp->mb[2] = mr->mb[2];
3839 mcp->mb[3] = mr->mb[3];
3840 mcp->mb[4] = mr->mb[4];
3841 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3842 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
3843 mcp->timeout = MAILBOX_TOV;
3844 rval = ql_mailbox_command(ha, mcp);
3845
3846 /* Return mailbox data. */
3847 if (mr != NULL) {
3848 mr->mb[0] = mcp->mb[0];
3849 mr->mb[2] = mcp->mb[2];
3850 mr->mb[3] = mcp->mb[3];
3851 mr->mb[4] = mcp->mb[4];
3852 }
3853
3854 if (rval != QL_SUCCESS) {
3855 EL(ha, "failed=%xh\n", rval);
3856 } else {
3857 /*EMPTY*/
3858 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3859 }
3860
3861 return (rval);
3862 }
3863
3864 /*
3865 * ql_get_timeout_parameters
3866 * Issue get timeout parameters mailbox command.
3867 *
3868 * Input:
3869 * ha: adapter state pointer.
3870 * mr: pointer to mailbox in/out parameters.
3871 *
3872 * Returns:
3873 * ql local function return status code.
3874 *
3875 * Context:
3876 * Kernel context.
3877 */
3878 int
3879 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
3880 {
3881 int rval;
3882 mbx_cmd_t mc = {0};
3883 mbx_cmd_t *mcp = &mc;
3884
3885 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3886
3887 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
3888 mcp->out_mb = MBX_0;
3889 mcp->in_mb = MBX_3|MBX_0;
3890 mcp->timeout = MAILBOX_TOV;
3891 rval = ql_mailbox_command(ha, mcp);
3892 if (rval == QL_SUCCESS) {
3893 /* Get 2 * R_A_TOV in seconds */
3894 if (CFG_IST(ha, CFG_CTRL_2200) || mcp->mb[3] == 0) {
3895 *tov = R_A_TOV_DEFAULT;
3896 } else {
3897 *tov = (uint16_t)(mcp->mb[3] / 10);
3898 if (mcp->mb[3] % 10 != 0) {
3899 *tov = (uint16_t)(*tov + 1);
3900 }
3901 /*
3902 * Adjust value to prevent driver timeout at the same
3903 * time as device.
3904 */
3905 *tov = (uint16_t)(*tov + 5);
3906 }
3907 } else {
3908 *tov = R_A_TOV_DEFAULT;
3909 }
3910
3911 if (rval != QL_SUCCESS) {
3912 EL(ha, "failed=%xh\n", rval);
3913 } else {
3914 /*EMPTY*/
3915 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3916 }
3917
3918 return (rval);
3919 }
3920
3921 /*
3922 * ql_stop_firmware
3923 * Issue stop firmware Mailbox Command.
3924 *
3925 * Input:
3926 * ha: adapter state pointer.
3927 *
3928 * Returns:
3929 * ql local function return status code.
3930 *
3931 * Context:
3932 * Kernel context.
3933 */
3934 int
3935 ql_stop_firmware(ql_adapter_state_t *ha)
3936 {
3937 int rval;
3938 mbx_cmd_t mc = {0};
3939 mbx_cmd_t *mcp = &mc;
3940
3941 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3942
3943 mcp->mb[0] = MBC_STOP_FIRMWARE;
3944 mcp->out_mb = MBX_1|MBX_0;
3945 mcp->in_mb = MBX_0;
3946 mcp->timeout = 2;
3947 rval = ql_mailbox_command(ha, mcp);
3948
3949 if (rval != QL_SUCCESS) {
3950 EL(ha, "failed=%xh\n", rval);
3951 } else {
3952 /*EMPTY*/
3953 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3954 }
3955
3956 return (rval);
3957 }
3958
3959 /*
3960 * ql_read_sfp
3961 * Issue Read SFP Mailbox command
3962 *
3963 * Input:
3964 * ha: adapter state pointer.
3965 * mem: pointer to dma memory object for command.
3966 * dev: Device address (A0h or A2h).
3967 * addr: Data address on SFP EEPROM (0–255).
3968 *
3969 * Returns:
3970 * ql local function return status code.
3971 *
3972 * Context:
3973 * Kernel context.
3974 */
3975 int
3976 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
3977 uint16_t addr)
3978 {
3979 int rval;
3980 mbx_cmd_t mc = {0};
3981 mbx_cmd_t *mcp = &mc;
3982
3983 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3984
3985 mcp->mb[0] = MBC_READ_SFP;
3986 mcp->mb[1] = dev;
3987 mcp->mb[2] = MSW(mem->cookies->dmac_address);
3988 mcp->mb[3] = LSW(mem->cookies->dmac_address);
3989 mcp->mb[6] = MSW(mem->cookies->dmac_notused);
3990 mcp->mb[7] = LSW(mem->cookies->dmac_notused);
3991 mcp->mb[8] = LSW(mem->size);
3992 mcp->mb[9] = addr;
3993 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3994 mcp->in_mb = MBX_1|MBX_0;
3995 mcp->timeout = MAILBOX_TOV;
3996 rval = ql_mailbox_command(ha, mcp);
3997
3998 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
3999 DDI_DMA_SYNC_FORKERNEL);
4000
4001 if (rval != QL_SUCCESS) {
4002 EL(ha, "failed=%xh\n", rval);
4003 } else {
4004 /*EMPTY*/
4005 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4006 }
4007
4008 return (rval);
4009 }
4010
4011 /*
4012 * ql_iidma_rate
4013 * Issue get/set iidma rate command
4014 *
4015 * Input:
4016 * ha: adapter state pointer.
4017 * loop_id: n-port handle to set/get iidma rate.
4018 * idma_rate: Pointer to iidma rate.
4019 * option: iidma firmware option (set or get data).
4020 * 0 --> Get iidma rate
4021 * 1 --> Set iidma rate
4022 *
4023 * Returns:
4024 * ql local function return status code.
4025 *
4026 * Context:
4027 * Kernel context.
4028 */
4029 int
4030 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
4031 uint32_t option)
4032 {
4033 int rval;
4034 mbx_cmd_t mc = {0};
4035 mbx_cmd_t *mcp = &mc;
4036
4037 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4038
4039 mcp->mb[0] = MBC_PORT_PARAM;
4040 mcp->mb[1] = loop_id;
4041 mcp->mb[2] = (uint16_t)option;
4042 mcp->out_mb = MBX_0|MBX_1|MBX_2;
4043 mcp->in_mb = MBX_0|MBX_1;
4044
4045 if (option & BIT_0) {
4046 mcp->mb[3] = (uint16_t)*idma_rate;
4047 mcp->out_mb |= MBX_3;
4048 } else {
4049 mcp->in_mb |= MBX_3;
4050 }
4051
4052 mcp->timeout = MAILBOX_TOV;
4053 rval = ql_mailbox_command(ha, mcp);
4054
4055 if (rval != QL_SUCCESS) {
4056 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
4057 } else {
4058 if (option == 0) {
4059 *idma_rate = mcp->mb[3];
4060 }
4061
4062 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4063 }
4064
4065 return (rval);
4066 }
4067
4068 /*
4069 * ql_set_xmit_parms
4070 * Set transmit parameters
4071 *
4072 * Input:
4073 * ha: adapter state pointer.
4074 *
4075 * Returns:
4076 * ql local function return status code.
4077 *
4078 * Context:
4079 * Kernel context.
4080 */
4081 int
4082 ql_set_xmit_parms(ql_adapter_state_t *ha)
4083 {
4084 int rval;
4085 mbx_cmd_t mc = {0};
4086 mbx_cmd_t *mcp = &mc;
4087
4088 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4089
4090 mcp->mb[0] = MBC_XMIT_PARM;
4091 mcp->mb[1] = BIT_1;
4092 mcp->out_mb = MBX_1|MBX_0;
4093 mcp->in_mb = MBX_0;
4094 mcp->timeout = MAILBOX_TOV;
4095 rval = ql_mailbox_command(ha, mcp);
4096
4097 if (rval != QL_SUCCESS) {
4098 EL(ha, "failed=%xh\n", rval);
4099 } else {
4100 /*EMPTY*/
4101 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4102 }
4103 return (rval);
4104 }
4105
4106 /*
4107 * ql_fw_etrace
4108 * Firmware extended tracing.
4109 *
4110 * Input:
4111 * ha: adapter state pointer.
4112 * mem: pointer to dma memory object for command.
4113 * opt: options and opcode.
4114 *
4115 * Returns:
4116 * ql local function return status code.
4117 *
4118 * Context:
4119 * Kernel context.
4120 */
4121 int
4122 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt)
4123 {
4124 int rval = QL_SUCCESS;
4125 mbx_cmd_t mc = {0};
4126 mbx_cmd_t *mcp = &mc;
4127 uint16_t op_code;
4128 uint64_t time;
4129
4130 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4131
4132 /* currently no supported options */
4133 op_code = (uint16_t)(opt & ~0xFF00);
4134
4135 mcp->mb[0] = MBC_TRACE_CONTROL;
4136 mcp->mb[1] = op_code;
4137 mcp->in_mb = MBX_0;
4138 mcp->timeout = MAILBOX_TOV;
4139
4140 switch (op_code) {
4141 case FTO_INSERT_TIME_STAMP:
4142
4143 (void) drv_getparm(TIME, &time);
4144
4145 EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
4146
4147 mcp->mb[2] = LSW(LSD(time));
4148 mcp->mb[3] = MSW(LSD(time));
4149 mcp->mb[4] = LSW(MSD(time));
4150 mcp->mb[5] = MSW(MSD(time));
4177 case FTO_FCE_TRACE_DISABLE:
4178 /* also causes ISP25xx to flush its internal FCE buffer. */
4179 mcp->mb[2] = BIT_0;
4180 mcp->out_mb = MBX_0_THRU_2;
4181 break;
4182
4183 case FTO_EXT_TRACE_DISABLE:
4184 /* just sending the opcode disables it */
4185 break;
4186
4187 default:
4188 EL(ha, "invalid option: %xh\n", opt);
4189 rval = QL_PARAMETER_ERROR;
4190 break;
4191 }
4192
4193 if (rval == QL_SUCCESS) {
4194 rval = ql_mailbox_command(ha, mcp);
4195 }
4196
4197 if (rval != QL_SUCCESS) {
4198 EL(ha, "failed=%xh\n", rval);
4199 } else {
4200 /*EMPTY*/
4201 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4202 }
4203
4204 return (rval);
4205 }
4206
4207 /*
4208 * ql_reset_menlo
4209 * Reset Menlo Mailbox Command.
4210 *
4211 * Input:
4212 * ha: adapter state pointer.
4213 * mr: pointer to mailbox in/out parameters.
4214 * opt: options.
4215 *
4216 * Returns:
4217 * ql local function return status code.
4218 *
4219 * Context:
4220 * Kernel context.
4221 */
4222 int
4223 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4224 {
4225 int rval;
4226 mbx_cmd_t mc = {0};
4227 mbx_cmd_t *mcp = &mc;
4228
4229 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4230
4231 mcp->mb[0] = MBC_RESET_MENLO;
4232 mcp->mb[1] = opt;
4233 mcp->out_mb = MBX_1|MBX_0;
4234 mcp->in_mb = MBX_1|MBX_0;
4235 mcp->timeout = MAILBOX_TOV;
4236 rval = ql_mailbox_command(ha, mcp);
4237
4238 /* Return mailbox data. */
4239 if (mr != NULL) {
4240 mr->mb[0] = mcp->mb[0];
4241 mr->mb[1] = mcp->mb[1];
4242 }
4243
4244 if (rval != QL_SUCCESS) {
4245 EL(ha, "failed=%xh\n", rval);
4246 } else {
4247 /*EMPTY*/
4248 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4249 }
4250
4251 return (rval);
4252 }
4253
4254 /*
4255 * ql_restart_mpi
4256 * The Restart MPI Firmware Mailbox Command will reset the MPI RISC,
4257 * reload MPI firmware from Flash, and execute the firmware.
4258 *
4259 * Input:
4260 * ha: adapter state pointer.
4261 *
4262 * Returns:
4263 * ql local function return status code.
4264 *
4265 * Context:
4266 * Kernel context.
4267 */
4268 int
4269 ql_restart_mpi(ql_adapter_state_t *ha)
4270 {
4271 int rval;
4272 mbx_cmd_t mc = {0};
4273 mbx_cmd_t *mcp = &mc;
4274
4275 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4276
4277 mcp->mb[0] = MBC_RESTART_MPI;
4278 mcp->out_mb = MBX_0;
4279 mcp->in_mb = MBX_1|MBX_0;
4280 mcp->timeout = MAILBOX_TOV;
4281 rval = ql_mailbox_command(ha, mcp);
4282
4283 /* Return mailbox data. */
4284 if (rval != QL_SUCCESS) {
4285 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
4286 } else {
4287 /*EMPTY*/
4288 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4289 }
4290
4291 return (rval);
4292 }
4293
4294 /*
4295 * ql_idc_request
4296 * Inter-Driver Communication Request.
4297 *
4298 * Input:
4299 * ha: adapter state pointer.
4300 * mr: pointer for mailbox data.
4301 *
4302 * Returns:
4303 * ql local function return status code.
4304 *
4305 * Context:
4306 * Kernel context.
4307 */
4308 int
4309 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4310 {
4311 int rval;
4312 mbx_cmd_t mc = {0};
4313 mbx_cmd_t *mcp = &mc;
4314
4315 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4316
4317 mcp->mb[0] = MBC_IDC_REQUEST;
4318 mcp->mb[1] = mr->mb[1];
4319 mcp->mb[2] = mr->mb[2];
4320 mcp->mb[3] = mr->mb[3];
4321 mcp->mb[4] = mr->mb[4];
4322 mcp->mb[5] = mr->mb[5];
4323 mcp->mb[6] = mr->mb[6];
4324 mcp->mb[7] = mr->mb[7];
4325 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4326 mcp->in_mb = MBX_2|MBX_0;
4327 mcp->timeout = MAILBOX_TOV;
4328 rval = ql_mailbox_command(ha, mcp);
4329
4330 if (rval == QL_SUCCESS) {
4331 if (mr != NULL) {
4332 mr->mb[2] = mcp->mb[2];
4333 }
4334 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4335 } else {
4336 EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]);
4337 }
4338
4339 return (rval);
4340 }
4341
4342 /*
4343 * ql_idc_ack
4344 * Inter-Driver Communication Acknowledgement.
4345 *
4346 * Input:
4347 * ha: adapter state pointer.
4348 *
4349 * Returns:
4350 * ql local function return status code.
4351 *
4352 * Context:
4353 * Kernel context.
4354 */
4355 int
4356 ql_idc_ack(ql_adapter_state_t *ha)
4357 {
4358 int rval;
4359 mbx_cmd_t mc = {0};
4360 mbx_cmd_t *mcp = &mc;
4361
4362 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4363
4364 mcp->mb[0] = MBC_IDC_ACK;
4365 mcp->mb[1] = ha->idc_mb[1];
4366 mcp->mb[2] = ha->idc_mb[2];
4367 mcp->mb[3] = ha->idc_mb[3];
4368 mcp->mb[4] = ha->idc_mb[4];
4369 mcp->mb[5] = ha->idc_mb[5];
4370 mcp->mb[6] = ha->idc_mb[6];
4371 mcp->mb[7] = ha->idc_mb[7];
4372 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4373 mcp->in_mb = MBX_0;
4374 mcp->timeout = MAILBOX_TOV;
4375 rval = ql_mailbox_command(ha, mcp);
4376
4377 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4378
4379 return (rval);
4380 }
4381
4382 /*
4383 * ql_idc_time_extend
4384 * Inter-Driver Communication Time Extend
4385 *
4386 * Input:
4387 * ha: adapter state pointer.
4388 * mr: pointer for mailbox data.
4389 *
4390 * Returns:
4391 * ql local function return status code.
4392 *
4393 * Context:
4394 * Kernel context.
4395 */
4396 int
4397 ql_idc_time_extend(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4398 {
4399 int rval;
4400 mbx_cmd_t mc = {0};
4401 mbx_cmd_t *mcp = &mc;
4402
4403 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4404
4405 mcp->mb[0] = MBC_IDC_TIME_EXTEND;
4406 mcp->mb[1] = mr->mb[1];
4407 mcp->mb[2] = mr->mb[2];
4408 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4409 mcp->in_mb = MBX_0;
4410 mcp->timeout = MAILBOX_TOV;
4411 rval = ql_mailbox_command(ha, mcp);
4412
4413 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4414
4415 return (rval);
4416 }
4417
4418 /*
4419 * ql_port_reset
4420 * The Port Reset for the external 10G port associated with this function.
4421 *
4422 * Input:
4423 * ha: adapter state pointer.
4424 *
4425 * Returns:
4426 * ql local function return status code.
4427 *
4428 * Context:
4429 * Kernel context.
4430 */
4431 int
4432 ql_port_reset(ql_adapter_state_t *ha)
4433 {
4434 int rval;
4435 mbx_cmd_t mc = {0};
4436 mbx_cmd_t *mcp = &mc;
4437
4438 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4439
4440 mcp->mb[0] = MBC_PORT_RESET;
4441 mcp->out_mb = MBX_0;
4442 mcp->in_mb = MBX_0;
4443 mcp->timeout = MAILBOX_TOV;
4444 rval = ql_mailbox_command(ha, mcp);
4445
4446 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4447
4448 return (rval);
4449 }
4450
4451 /*
4452 * ql_set_port_config
4453 * The Set Port Configuration command sets the configuration for the
4454 * external 10G port associated with this function.
4455 *
4456 * Input:
4457 * ha: adapter state pointer.
4458 * mr: pointer for mailbox data.
4459 *
4460 * Returns:
4461 * ql local function return status code.
4462 *
4463 * Context:
4464 * Kernel context.
4465 */
4466 int
4467 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4468 {
4469 int rval;
4470 mbx_cmd_t mc = {0};
4471 mbx_cmd_t *mcp = &mc;
4472
4473 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4474
4475 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4476 mcp->mb[1] = mrp->mb[1];
4477 mcp->mb[2] = mrp->mb[2];
4478 mcp->mb[3] = mrp->mb[3];
4479 mcp->mb[4] = mrp->mb[4];
4480 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4481 mcp->in_mb = MBX_0;
4482 mcp->timeout = MAILBOX_TOV;
4483 rval = ql_mailbox_command(ha, mcp);
4484
4485 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4486
4487 return (rval);
4488 }
4489
4490 /*
4491 * ql_get_port_config
4492 * The Get Port Configuration command retrieves the current configuration
4493 * for the external 10G port associated with this function.
4494 *
4495 * Input:
4496 * ha: adapter state pointer.
4497 * mr: pointer for mailbox data.
4498 *
4499 * Returns:
4500 * ql local function return status code.
4501 *
4502 * Context:
4503 * Kernel context.
4504 */
4505 int
4506 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4507 {
4508 int rval;
4509 mbx_cmd_t mc = {0};
4510 mbx_cmd_t *mcp = &mc;
4511
4512 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4513
4514 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4515 mcp->out_mb = MBX_0;
4516 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4517 mcp->timeout = MAILBOX_TOV;
4518 rval = ql_mailbox_command(ha, mcp);
4519
4520 if (rval == QL_SUCCESS) {
4521 if (mrp != NULL) {
4522 mrp->mb[1] = mcp->mb[1];
4523 mrp->mb[2] = mcp->mb[2];
4524 mrp->mb[3] = mcp->mb[3];
4525 mrp->mb[4] = mcp->mb[4];
4526 }
4527 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4528 } else {
4529 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n",
4530 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]);
4531 }
4532
4533 return (rval);
4534 }
4535
4536 /*
4537 * ql_flash_access
4538 * The Get Port Configuration command retrieves the current configuration
4539 * for the external 10G port associated with this function
4540 *
4541 * Input:
4542 * ha: adapter state pointer.
4543 * cmd: command.
4544 * start: 32bit word address.
4545 * end: 32bit word address.
4546 * dp: 32bit word pointer.
4547 *
4548 * Returns:
4549 * ql local function return status code.
4550 *
4551 * Context:
4552 * Kernel context.
4553 */
4554 int
4555 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start,
4556 uint32_t end, uint32_t *dp)
4557 {
4558 int rval;
4559 mbx_cmd_t mc = {0};
4560 mbx_cmd_t *mcp = &mc;
4561
4562 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4563
4564 mcp->mb[0] = MBC_FLASH_ACCESS;
4565 if (cmd > 0 && cmd < 4) {
4566 mcp->mb[1] = (uint16_t)(FAC_FORCE_SEMA_LOCK | cmd);
4567 } else {
4568 mcp->mb[1] = cmd;
4569 }
4570 mcp->mb[2] = LSW(start);
4571 mcp->mb[3] = MSW(start);
4572 mcp->mb[4] = LSW(end);
4573 mcp->mb[5] = MSW(end);
4574
4575 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4576 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4577 mcp->timeout = MAILBOX_TOV;
4578 rval = ql_mailbox_command(ha, mcp);
4579
4580 if (rval != QL_SUCCESS) {
4581 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4582 mcp->mb[2]);
4583 } else {
4584 if (dp != NULL) {
4585 *dp = (uint32_t)mcp->mb[1];
4586 }
4587 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4588 }
4589
4590 return (rval);
4591 }
4592
4593 /*
4594 * ql_get_xgmac_stats
4595 * Issue et XGMAC Statistics Mailbox command
4596 *
4597 * Input:
4598 * ha: adapter state pointer.
4599 * size: size of data buffer.
4600 * bufp: data pointer for DMA data.
4601 *
4602 * Returns:
4603 * ql local function return status code.
4604 *
4605 * Context:
4606 * Kernel context.
4607 */
4608 int
4609 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
4610 {
4611 int rval;
4612 dma_mem_t mem_desc;
4613 mbx_cmd_t mc = {0};
4614 mbx_cmd_t *mcp = &mc;
4615
4616 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4617
4618 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4619 (uint32_t)size)) != QL_SUCCESS) {
4620 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
4621 return (QL_MEMORY_ALLOC_FAILED);
4622 }
4623
4624 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4625 mcp->mb[2] = MSW(mem_desc.cookie.dmac_address);
4626 mcp->mb[3] = LSW(mem_desc.cookie.dmac_address);
4627 mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused);
4628 mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused);
4629 mcp->mb[8] = (uint16_t)(size >> 2);
4630 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4631 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4632 mcp->timeout = MAILBOX_TOV;
4633 rval = ql_mailbox_command(ha, mcp);
4634
4635 if (rval == QL_SUCCESS) {
4636 ql_get_mbox_dma_data(&mem_desc, bufp);
4637 }
4638 ql_free_dma_resource(ha, &mem_desc);
4639
4640 if (rval != QL_SUCCESS) {
4641 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4642 mcp->mb[2]);
4643 } else {
4644 /*EMPTY*/
4645 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4646 }
4647
4648 return (rval);
4649 }
4650
4651 /*
4652 * ql_get_dcbx_params
4653 * Issue get DCBX parameters mailbox command.
4654 *
4655 * Input:
4656 * ha: adapter state pointer.
4657 * size: size of data buffer.
4658 * bufp: data pointer for DMA data.
4659 *
4660 * Returns:
4661 * ql local function return status code.
4662 *
4663 * Context:
4664 * Kernel context.
4665 */
4666 int
4667 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp)
4668 {
4669 int rval;
4670 dma_mem_t mem_desc;
4671 mbx_cmd_t mc = {0};
4672 mbx_cmd_t *mcp = &mc;
4673
4674 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4675
4676 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) !=
4677 QL_SUCCESS) {
4678 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4679 return (QL_MEMORY_ALLOC_FAILED);
4680 }
4681
4682 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4683 mcp->mb[1] = 0; /* Return all DCBX paramters */
4684 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4685 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4686 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4687 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4688 mcp->mb[8] = (uint16_t)size;
4689 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4690 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4691 mcp->timeout = MAILBOX_TOV;
4692 rval = ql_mailbox_command(ha, mcp);
4693
4694 if (rval == QL_SUCCESS) {
4695 ql_get_mbox_dma_data(&mem_desc, bufp);
4696 }
4697
4698 ql_free_dma_resource(ha, &mem_desc);
4699
4700 if (rval != QL_SUCCESS) {
4701 EL(ha, "failed=%xh\n", rval);
4702 } else {
4703 /*EMPTY*/
4704 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4705 }
4706
4707 return (rval);
4708 }
4709 /*
4710 * ql_get_fcf_list
4711 * Issue get FCF list mailbox command.
4712 *
4713 * Input:
4714 * ha: adapter state pointer.
4715 * fcf_list: pointer to ql_fcf_list_desc_t
4716 * bufp: data pointer for DMA data.
4717 *
4718 * Returns:
4719 * ql local function return status code.
4720 *
4721 * Context:
4722 * Kernel context.
4723 */
4724
4725 int
4726 ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list,
4727 caddr_t bufp)
4728 {
4729 int rval;
4730 dma_mem_t mem_desc;
4731 mbx_cmd_t mc = {0};
4732 mbx_cmd_t *mcp = &mc;
4733
4734 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4735
4736 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4737 fcf_list->buffer_size)) !=
4738 QL_SUCCESS) {
4739 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4740 return (QL_MEMORY_ALLOC_FAILED);
4741 }
4742
4743 mcp->mb[0] = MBC_GET_FCF_LIST;
4744 mcp->mb[1] = fcf_list->options;
4745 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4746 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4747 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4748 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4749 mcp->mb[8] = (uint16_t)fcf_list->buffer_size;
4750 mcp->mb[9] = fcf_list->fcf_index;
4751 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4752 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4753 mcp->timeout = MAILBOX_TOV;
4754 rval = ql_mailbox_command(ha, mcp);
4755
4756 if (rval == QL_SUCCESS) {
4757 ql_get_mbox_dma_data(&mem_desc, bufp);
4758 fcf_list->buffer_size = (uint16_t)mcp->mb[1];
4759 }
4760
4761 ql_free_dma_resource(ha, &mem_desc);
4762
4763 if (rval != QL_SUCCESS) {
4764 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4765 mcp->mb[2]);
4766 } else {
4767 /*EMPTY*/
4768 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4769 }
4770
4771 return (rval);
4772 }
4773
4774 /*
4775 * ql_get_resource_cnts
4776 * Issue get Resourse Count mailbox command.
4777 *
4778 * Input:
4779 * ha: adapter state pointer.
4780 * mr: pointer for mailbox data.
4781 *
4782 * Returns:
4783 * ql local function return status code.
4784 *
4785 * Context:
4786 * Kernel context.
4787 */
4788
4789 int
4790 ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4791 {
4792 int rval;
4793 mbx_cmd_t mc = {0};
4794 mbx_cmd_t *mcp = &mc;
4795
4796 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4797
4798 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
4799 mcp->out_mb = MBX_0;
4800 mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
4801 MBX_3|MBX_2|MBX_1|MBX_0;
4802 mcp->timeout = MAILBOX_TOV;
4803 rval = ql_mailbox_command(ha, mcp);
4804
4805 /* Return mailbox data. */
4806 if (mr != NULL) {
4807 mr->mb[1] = mcp->mb[1];
4808 mr->mb[2] = mcp->mb[2];
4809 mr->mb[3] = mcp->mb[3];
4810 mr->mb[6] = mcp->mb[6];
4811 mr->mb[7] = mcp->mb[7];
4812 mr->mb[10] = mcp->mb[10];
4813 mr->mb[11] = mcp->mb[11];
4814 mr->mb[12] = mcp->mb[12];
4815 }
4816
4817 if (rval != QL_SUCCESS) {
4818 EL(ha, "failed=%xh\n", rval);
4819 } else {
4820 /*EMPTY*/
4821 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4822 }
4823
4824 return (rval);
4825 }
4826
4827 /*
4828 * ql_toggle_interrupt
4829 * Issue Toggle Interrupt Mailbox Command.
4830 *
4831 * Input:
4832 * ha: adapter state pointer.
4833 * opt: 0 = disable, 1 = enable.
4834 *
4835 * Returns:
4836 * ql local function return status code.
4837 *
4838 * Context:
4839 * Kernel context.
4840 */
4841 int
4842 ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt)
4843 {
4844 int rval;
4845 mbx_cmd_t mc = {0};
4846 mbx_cmd_t *mcp = &mc;
4847
4848 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4849
4850 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
4851 mcp->mb[1] = opt;
4852 mcp->out_mb = MBX_1|MBX_0;
4853 mcp->in_mb = MBX_0;
4854 mcp->timeout = 2;
4855 rval = ql_mailbox_command(ha, mcp);
4856
4857 if (rval != QL_SUCCESS) {
4858 EL(ha, "failed=%xh\n", rval);
4859 } else {
4860 /*EMPTY*/
4861 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4862 }
4863
4864 return (rval);
4865 }
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /* Copyright 2015 QLogic Corporation */
23
24 /*
25 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
26 */
27
28 #pragma ident "Copyright 2015 QLogic Corporation; ql_mbx.c"
29
30 /*
31 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32 *
33 * ***********************************************************************
34 * * **
35 * * NOTICE **
36 * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION **
37 * * ALL RIGHTS RESERVED **
38 * * **
39 * ***********************************************************************
40 *
41 */
42
43 #include <ql_apps.h>
44 #include <ql_api.h>
45 #include <ql_debug.h>
46 #include <ql_iocb.h>
47 #include <ql_isr.h>
48 #include <ql_mbx.h>
49 #include <ql_nx.h>
50 #include <ql_xioctl.h>
51
52 /*
53 * Local data
54 */
55
56 /*
57 * Local prototypes
58 */
59 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
60 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint64_t,
61 uint32_t, uint16_t);
62 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
63 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
64 caddr_t, uint32_t);
65 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
66 uint32_t);
67 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
68 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
69 static int ql_init_req_q(ql_adapter_state_t *, ql_request_q_t *, uint16_t);
70 static int ql_init_rsp_q(ql_adapter_state_t *, ql_response_q_t *, uint16_t);
71 /*
72 * ql_mailbox_command
73 * Issue mailbox command and waits for completion.
74 *
75 * Input:
76 * ha = adapter state pointer.
77 * mcp = mailbox command parameter structure pointer.
78 *
79 * Returns:
80 * ql local function return status code.
81 *
82 * Context:
83 * Kernel context.
84 */
85 static int
86 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
87 {
88 uint16_t cnt;
89 uint32_t data;
90 clock_t timer, cv_stat;
91 int rval;
92 uint32_t set_flags = 0;
93 uint32_t reset_flags = 0;
94 ql_adapter_state_t *ha = vha->pha;
95 int mbx_cmd = mcp->mb[0];
96
97 QL_PRINT_3(ha, "started, cmd=%xh\n", mbx_cmd);
98
99 /* Acquire mailbox register lock. */
100 MBX_REGISTER_LOCK(ha);
101
102 /* Check for mailbox available, if not wait for signal. */
103 while (ha->mailbox_flags & MBX_BUSY_FLG) {
104 if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
105 EL(vha, "powerdown availability cmd=%xh\n", mcp->mb[0]);
106 MBX_REGISTER_UNLOCK(ha);
107 return (QL_LOCK_TIMEOUT);
108 }
109 ha->mailbox_flags = (uint8_t)
110 (ha->mailbox_flags | MBX_WANT_FLG);
111
112 /* Set timeout after command that is running. */
113 timer = ha->mailbox_flags & MBX_BUSY_FLG ?
114 (mcp->timeout + 20) : 2;
115 timer = timer * drv_usectohz(1000000);
116 cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
117 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
118 if (cv_stat == -1 || cv_stat == 0) {
119 /*
120 * The timeout time 'timer' was
121 * reached without the condition
122 * being signaled.
123 */
124 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
125 ~MBX_WANT_FLG);
126 cv_broadcast(&ha->cv_mbx_wait);
127
128 /* Release mailbox register lock. */
129 MBX_REGISTER_UNLOCK(ha);
130
131 if (cv_stat == 0) {
132 EL(vha, "waiting for availability aborted, "
133 "cmd=%xh\n", mcp->mb[0]);
134 return (QL_ABORTED);
135 }
137 return (QL_LOCK_TIMEOUT);
138 }
139 }
140
141 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
142
143 /* Structure pointer for return mailbox registers. */
144 ha->mcp = mcp;
145
146 /* Load mailbox registers. */
147 data = mcp->out_mb;
148 for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
149 if (data & MBX_0) {
150 WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
151 }
152 data >>= 1;
153 }
154
155 /* Issue set host interrupt command. */
156 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
157 if (CFG_IST(ha, CFG_CTRL_82XX)) {
158 WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
159 } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
160 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
161 } else {
162 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
163 }
164
165 /* Wait for command to complete. */
166 if (ha->flags & INTERRUPTS_ENABLED &&
167 !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) &&
168 !ddi_in_panic()) {
169 timer = mcp->timeout * drv_usectohz(1000000);
170 while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
171 !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
172
173 if (cv_reltimedwait(&ha->cv_mbx_intr,
174 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
175 /*
176 * The timeout time 'timer' was
177 * reached without the condition
178 * being signaled.
179 */
180 EL(vha, "reltimedwait expired cmd=%xh\n",
181 mcp->mb[0]);
182 MBX_REGISTER_UNLOCK(ha);
183 while (INTERRUPT_PENDING(ha)) {
184 (void) ql_isr((caddr_t)ha);
185 INTR_LOCK(ha);
186 ha->intr_claimed = B_TRUE;
187 INTR_UNLOCK(ha);
188 }
189 MBX_REGISTER_LOCK(ha);
190 break;
191 }
192 }
193 } else {
194 /* Release mailbox register lock. */
195 MBX_REGISTER_UNLOCK(ha);
196
197 /* Acquire interrupt lock. */
198 for (timer = mcp->timeout * 100; timer; timer--) {
199 /* Check for pending interrupts. */
200 while (INTERRUPT_PENDING(ha)) {
201 (void) ql_isr((caddr_t)ha);
210 }
211 if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
212 ha->task_daemon_flags & ISP_ABORT_NEEDED) {
213 break;
214 } else if (!ddi_in_panic() && timer % 101 == 0) {
215 delay(drv_usectohz(10000));
216 } else {
217 drv_usecwait(10000);
218 }
219 }
220
221 /* Acquire mailbox register lock. */
222 MBX_REGISTER_LOCK(ha);
223 }
224
225 /* Mailbox command timeout? */
226 if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
227 ha->mailbox_flags & MBX_ABORT) {
228 rval = QL_ABORTED;
229 } else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
230 if (!CFG_IST(ha, CFG_CTRL_82XX)) {
231 if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
232 (void) ql_binary_fw_dump(ha, FALSE);
233 }
234 EL(vha, "command timeout, isp_abort_needed\n");
235 set_flags |= ISP_ABORT_NEEDED;
236 }
237 rval = QL_FUNCTION_TIMEOUT;
238 } else {
239 ha->mailbox_flags = (uint8_t)
240 (ha->mailbox_flags & ~MBX_INTERRUPT);
241 /*
242 * This is the expected completion path so
243 * return the actual mbx cmd completion status.
244 */
245 rval = mcp->mb[0];
246 }
247
248 /*
249 * Clear outbound to risc mailbox registers per spec. The exception
250 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
251 * so avoid writing them.
252 */
253 if (CFG_IST(ha, CFG_CTRL_22XX)) {
254 data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
255 } else {
256 data = (mcp->out_mb >> 1);
257 }
258 for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
259 if (data & MBX_0) {
260 WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
261 }
262 data >>= 1;
263 }
264
265 /* Reset busy status. */
266 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
267 ~(MBX_BUSY_FLG | MBX_ABORT));
268 ha->mcp = NULL;
269
270 /* If thread is waiting for mailbox go signal it to start. */
271 if (ha->mailbox_flags & MBX_WANT_FLG) {
272 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
273 ~MBX_WANT_FLG);
274 cv_broadcast(&ha->cv_mbx_wait);
275 }
276
277 /* Release mailbox register lock. */
278 MBX_REGISTER_UNLOCK(ha);
279
280 if (set_flags != 0 || reset_flags != 0) {
281 ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
282 }
283
284 if (rval != QL_SUCCESS) {
285 EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
286 mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
287 } else {
288 /*EMPTY*/
289 QL_PRINT_3(ha, "done\n");
290 }
291
292 return (rval);
293 }
294
295 /*
296 * ql_setup_mbox_dma_resources
297 * Prepare the data for a mailbox dma transfer.
298 *
299 * Input:
300 * ha = adapter state pointer.
301 * mem_desc = descriptor to contain the dma resource information.
302 * data = pointer to the data.
303 * size = size of the data in bytes.
304 *
305 * Returns:
306 * ql local function return status code.
307 *
308 * Context:
309 * Kernel context.
412 * ha = adapter state pointer.
413 * ha->ip_init_ctrl_blk = setup for transmit.
414 *
415 * Returns:
416 * ql local function return status code.
417 *
418 * Context:
419 * Kernel context.
420 */
421 int
422 ql_initialize_ip(ql_adapter_state_t *ha)
423 {
424 ql_link_t *link;
425 ql_tgt_t *tq;
426 uint16_t index;
427 int rval;
428 dma_mem_t mem_desc;
429 mbx_cmd_t mc = {0};
430 mbx_cmd_t *mcp = &mc;
431
432 QL_PRINT_3(ha, "started\n");
433
434 if (!CFG_IST(ha, CFG_FCIP_SUPPORT) || ha->vp_index != 0) {
435 ha->flags &= ~IP_INITIALIZED;
436 EL(ha, "HBA does not support IP\n");
437 return (QL_FUNCTION_FAILED);
438 }
439
440 ha->rcvbuf_ring_ptr = ha->rcv_ring.bp;
441 ha->rcvbuf_ring_index = 0;
442
443 /* Reset all sequence counts. */
444 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
445 for (link = ha->dev[index].first; link != NULL;
446 link = link->next) {
447 tq = link->base_address;
448 tq->ub_total_seg_cnt = 0;
449 }
450 }
451
452 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
453 (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
454 if (rval != QL_SUCCESS) {
455 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
456 return (rval);
457 }
458
459 mcp->mb[0] = MBC_INITIALIZE_IP;
460 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
461 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
462 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
463 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
464 mcp->mb[8] = 0;
465 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
466 mcp->in_mb = MBX_8|MBX_0;
467 mcp->timeout = MAILBOX_TOV;
468 rval = ql_mailbox_command(ha, mcp);
469
470 ql_free_dma_resource(ha, &mem_desc);
471
472 if (rval == QL_SUCCESS) {
473 ADAPTER_STATE_LOCK(ha);
474 ha->flags |= IP_INITIALIZED;
475 ADAPTER_STATE_UNLOCK(ha);
476 QL_PRINT_3(ha, "done\n");
477 } else {
478 ha->flags &= ~IP_INITIALIZED;
479 EL(ha, "failed, rval = %xh\n", rval);
480 }
481 return (rval);
482 }
483
484 /*
485 * ql_shutdown_ip
486 * Disconnects firmware IP from system buffers.
487 *
488 * Input:
489 * ha = adapter state pointer.
490 *
491 * Returns:
492 * ql local function return status code.
493 *
494 * Context:
495 * Kernel context.
496 */
497 int
498 ql_shutdown_ip(ql_adapter_state_t *ha)
499 {
500 int rval;
501 mbx_cmd_t mc = {0};
502 mbx_cmd_t *mcp = &mc;
503 fc_unsol_buf_t *ubp;
504 ql_srb_t *sp;
505 uint16_t index;
506
507 QL_PRINT_3(ha, "started\n");
508
509 mcp->mb[0] = MBC_UNLOAD_IP;
510 mcp->out_mb = MBX_0;
511 mcp->in_mb = MBX_0;
512 mcp->timeout = MAILBOX_TOV;
513 rval = ql_mailbox_command(ha, mcp);
514
515 ADAPTER_STATE_LOCK(ha);
516 QL_UB_LOCK(ha);
517 /* Return all unsolicited buffers that ISP-IP has. */
518 for (index = 0; index < QL_UB_LIMIT; index++) {
519 ubp = ha->ub_array[index];
520 if (ubp != NULL) {
521 sp = ubp->ub_fca_private;
522 sp->flags &= ~SRB_UB_IN_ISP;
523 }
524 }
525
526 ha->ub_outcnt = 0;
527 QL_UB_UNLOCK(ha);
528 ha->flags &= ~IP_INITIALIZED;
529 ADAPTER_STATE_UNLOCK(ha);
530
531 if (rval == QL_SUCCESS) {
532 /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
533 QL_PRINT_3(ha, "done\n");
534 } else {
535 EL(ha, "failed, rval = %xh\n", rval);
536 }
537 return (rval);
538 }
539
540 /*
541 * ql_online_selftest
542 * Issue online self test mailbox command.
543 *
544 * Input:
545 * ha = adapter state pointer.
546 *
547 * Returns:
548 * ql local function return status code.
549 *
550 * Context:
551 * Kernel context.
552 */
553 int
554 ql_online_selftest(ql_adapter_state_t *ha)
555 {
556 int rval;
557 mbx_cmd_t mc = {0};
558 mbx_cmd_t *mcp = &mc;
559
560 QL_PRINT_3(ha, "started\n");
561
562 mcp->mb[0] = MBC_ONLINE_SELF_TEST;
563 mcp->out_mb = MBX_0;
564 mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
565 mcp->timeout = MAILBOX_TOV;
566 rval = ql_mailbox_command(ha, mcp);
567
568 if (rval != QL_SUCCESS) {
569 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
570 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
571 } else {
572 /*EMPTY*/
573 QL_PRINT_3(ha, "done\n");
574 }
575 return (rval);
576 }
577
578 /*
579 * ql_loop_back
580 * Issue diagnostic loop back frame mailbox command.
581 *
582 * Input:
583 * ha: adapter state pointer.
584 * findex: FCF index.
585 * lb: loop back parameter structure pointer.
586 *
587 * Returns:
588 * ql local function return status code.
589 *
590 * Context:
591 * Kernel context.
592 */
593 #ifndef apps_64bit
594 int
595 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
596 uint32_t h_xmit, uint32_t h_rcv)
597 {
598 int rval;
599 mbx_cmd_t mc = {0};
600 mbx_cmd_t *mcp = &mc;
601
602 QL_PRINT_3(ha, "started\n");
603
604 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
605 mcp->mb[1] = lb->options;
606 mcp->mb[2] = findex;
607 mcp->mb[6] = LSW(h_rcv);
608 mcp->mb[7] = MSW(h_rcv);
609 mcp->mb[10] = LSW(lb->transfer_count);
610 mcp->mb[11] = MSW(lb->transfer_count);
611 mcp->mb[12] = lb->transfer_segment_count;
612 mcp->mb[13] = lb->receive_segment_count;
613 mcp->mb[14] = LSW(lb->transfer_data_address);
614 mcp->mb[15] = MSW(lb->transfer_data_address);
615 mcp->mb[16] = LSW(lb->receive_data_address);
616 mcp->mb[17] = MSW(lb->receive_data_address);
617 mcp->mb[18] = LSW(lb->iteration_count);
618 mcp->mb[19] = MSW(lb->iteration_count);
619 mcp->mb[20] = LSW(h_xmit);
620 mcp->mb[21] = MSW(h_xmit);
621 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
622 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
623 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
624 mcp->timeout = lb->iteration_count / 300;
625
626 if (mcp->timeout < MAILBOX_TOV) {
627 mcp->timeout = MAILBOX_TOV;
628 }
629
630 rval = ql_mailbox_command(ha, mcp);
631
632 if (rval != QL_SUCCESS) {
633 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
634 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
635 } else {
636 /*EMPTY*/
637 QL_PRINT_3(ha, "done\n");
638 }
639 return (rval);
640 }
641 #else
642 int
643 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
644 {
645 int rval;
646 mbx_cmd_t mc = {0};
647 mbx_cmd_t *mcp = &mc;
648
649 QL_PRINT_3(ha, "started\n");
650
651 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
652 mcp->mb[1] = lb->options;
653 mcp->mb[2] = findex;
654 mcp->mb[6] = LSW(h_rcv);
655 mcp->mb[7] = MSW(h_rcv);
656 mcp->mb[6] = LSW(MSD(lb->receive_data_address));
657 mcp->mb[7] = MSW(MSD(lb->receive_data_address));
658 mcp->mb[10] = LSW(lb->transfer_count);
659 mcp->mb[11] = MSW(lb->transfer_count);
660 mcp->mb[12] = lb->transfer_segment_count;
661 mcp->mb[13] = lb->receive_segment_count;
662 mcp->mb[14] = LSW(lb->transfer_data_address);
663 mcp->mb[15] = MSW(lb->transfer_data_address);
664 mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
665 mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
666 mcp->mb[16] = LSW(lb->receive_data_address);
667 mcp->mb[17] = MSW(lb->receive_data_address);
668 mcp->mb[16] = LSW(LSD(lb->receive_data_address));
669 mcp->mb[17] = MSW(LSD(lb->receive_data_address));
671 mcp->mb[19] = MSW(lb->iteration_count);
672 mcp->mb[20] = LSW(h_xmit);
673 mcp->mb[21] = MSW(h_xmit);
674 mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
675 mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
676 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
677 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
678 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
679 mcp->timeout = lb->iteration_count / 300;
680
681 if (mcp->timeout < MAILBOX_TOV) {
682 mcp->timeout = MAILBOX_TOV;
683 }
684
685 rval = ql_mailbox_command(ha, mcp);
686
687 if (rval != QL_SUCCESS) {
688 EL(ha, "failed, rval = %xh\n", rval);
689 } else {
690 /*EMPTY*/
691 QL_PRINT_3(ha, "done\n");
692 }
693 return (rval);
694 }
695 #endif
696
697 /*
698 * ql_echo
699 * Issue an ELS echo using the user specified data to a user specified
700 * destination
701 *
702 * Input:
703 * ha: adapter state pointer.
704 * findex: FCF index.
705 * echo_pt: echo parameter structure pointer.
706 *
707 * Returns:
708 * ql local function return status code.
709 *
710 * Context:
711 * Kernel context.
712 */
713 int
714 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
715 {
716 int rval;
717 mbx_cmd_t mc = {0};
718 mbx_cmd_t *mcp = &mc;
719
720 QL_PRINT_3(ha, "started\n");
721
722 mcp->mb[0] = MBC_ECHO; /* ECHO command */
723 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */
724 /* addressing (bit 6) and */
725 /* real echo (bit 15 */
726 mcp->mb[2] = findex;
727
728 /*
729 * I know this looks strange, using a field labled "not used"
730 * The way the ddi_dma_cookie_t structure/union is defined
731 * is a union of one 64 bit entity with an array of two 32
732 * bit enititys. Since we have routines to convert 32 bit
733 * entities into 16 bit entities it is easier to use
734 * both 32 bit union members then the one 64 bit union
735 * member
736 */
737 if (echo_pt->options & BIT_6) {
738 /* 64 bit addressing */
739 /* Receive data dest add in system memory bits 47-32 */
740 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
758 /* Transmit data source address in system memory bits 31-16 */
759 mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
760
761 /* Receive data destination address in system memory bits 15-0 */
762 mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
763
764 /* Receive data destination address in system memory bits 31-16 */
765 mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
766
767 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
768 MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
769 mcp->in_mb = MBX_3|MBX_1|MBX_0;
770 mcp->timeout = MAILBOX_TOV;
771
772 rval = ql_mailbox_command(ha, mcp);
773
774 if (rval != QL_SUCCESS) {
775 EL(ha, "failed, rval = %xh\n", rval);
776 } else {
777 /*EMPTY*/
778 QL_PRINT_3(ha, "done\n");
779 }
780 return (rval);
781 }
782
783 /*
784 * ql_send_change_request
785 * Issue send change request mailbox command.
786 *
787 * Input:
788 * ha: adapter state pointer.
789 * fmt: Registration format.
790 *
791 * Returns:
792 * ql local function return status code.
793 *
794 * Context:
795 * Kernel context.
796 */
797 int
798 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
799 {
800 int rval;
801 mbx_cmd_t mc = {0};
802 mbx_cmd_t *mcp = &mc;
803
804 QL_PRINT_3(ha, "started\n");
805
806 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
807 mcp->mb[1] = fmt;
808 mcp->out_mb = MBX_1|MBX_0;
809 if (ha->flags & VP_ENABLED) {
810 mcp->mb[9] = ha->vp_index;
811 mcp->out_mb |= MBX_9;
812 }
813 mcp->in_mb = MBX_0;
814 mcp->timeout = MAILBOX_TOV;
815 rval = ql_mailbox_command(ha, mcp);
816
817 if (rval != QL_SUCCESS) {
818 EL(ha, "failed=%xh\n", rval);
819 } else {
820 /*EMPTY*/
821 QL_PRINT_3(ha, "done\n");
822 }
823 return (rval);
824 }
825
826 /*
827 * ql_send_lfa
828 * Send a Loop Fabric Address mailbox command.
829 *
830 * Input:
831 * ha: adapter state pointer.
832 * lfa: LFA command structure pointer.
833 *
834 * Returns:
835 * ql local function return status code.
836 *
837 * Context:
838 * Kernel context.
839 */
840 int
841 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
842 {
843 int rval;
844 uint16_t size;
845 dma_mem_t mem_desc;
846 mbx_cmd_t mc = {0};
847 mbx_cmd_t *mcp = &mc;
848
849 QL_PRINT_3(ha, "started\n");
850
851 /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
852 size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
853
854 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
855 if (rval != QL_SUCCESS) {
856 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
857 return (rval);
858 }
859
860 mcp->mb[0] = MBC_SEND_LFA_COMMAND;
861 mcp->mb[1] = (uint16_t)(size >> 1);
862 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
863 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
864 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
865 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
866 mcp->in_mb = MBX_0;
867 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
868 if (ha->flags & VP_ENABLED) {
869 mcp->mb[9] = ha->vp_index;
870 mcp->out_mb |= MBX_9;
871 }
872 mcp->timeout = MAILBOX_TOV;
873 rval = ql_mailbox_command(ha, mcp);
874
875 ql_free_dma_resource(ha, &mem_desc);
876
877 if (rval != QL_SUCCESS) {
878 EL(ha, "failed, rval = %xh\n", rval);
879 } else {
880 /*EMPTY*/
881 QL_PRINT_3(ha, "done\n");
882 }
883
884 return (rval);
885 }
886
887 /*
888 * ql_clear_aca
889 * Issue clear ACA mailbox command.
890 *
891 * Input:
892 * ha: adapter state pointer.
893 * tq: target queue pointer.
894 * lq: LUN queue pointer.
895 *
896 * Returns:
897 * ql local function return status code.
898 *
899 * Context:
900 * Kernel context.
901 */
902 int
903 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
904 {
905 int rval;
906 mbx_cmd_t mc = {0};
907 mbx_cmd_t *mcp = &mc;
908
909 QL_PRINT_3(ha, "started\n");
910
911 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
912 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
913 CF_CLEAR_ACA, 0);
914 } else {
915 mcp->mb[0] = MBC_CLEAR_ACA;
916 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
917 mcp->mb[1] = tq->loop_id;
918 } else {
919 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
920 }
921 mcp->mb[2] = lq->lun_no;
922 mcp->out_mb = MBX_2|MBX_1|MBX_0;
923 mcp->in_mb = MBX_0;
924 mcp->timeout = MAILBOX_TOV;
925 rval = ql_mailbox_command(ha, mcp);
926 }
927
928 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
929
930 if (rval != QL_SUCCESS) {
931 EL(ha, "failed, rval = %xh\n", rval);
932 } else {
933 /*EMPTY*/
934 QL_PRINT_3(ha, "done\n");
935 }
936
937 return (rval);
938 }
939
940 /*
941 * ql_target_reset
942 * Issue target reset mailbox command.
943 *
944 * Input:
945 * ha: adapter state pointer.
946 * tq: target queue pointer.
947 * delay: seconds.
948 *
949 * Returns:
950 * ql local function return status code.
951 *
952 * Context:
953 * Kernel context.
954 */
955 int
956 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
957 {
958 ql_link_t *link;
959 ql_srb_t *sp;
960 uint16_t index;
961 int rval = QL_SUCCESS;
962 mbx_cmd_t mc = {0};
963 mbx_cmd_t *mcp = &mc;
964
965 QL_PRINT_3(ha, "started\n");
966
967 ql_requeue_pending_cmds(ha, tq);
968 INTR_LOCK(ha);
969 for (index = 1; index < ha->pha->osc_max_cnt; index++) {
970 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
971 sp->lun_queue != NULL &&
972 sp->lun_queue->target_queue == tq) {
973 sp->flags |= SRB_ABORTING;
974 }
975 }
976 INTR_UNLOCK(ha);
977
978 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
979 /* queue = NULL, all targets. */
980 if (tq == NULL) {
981 for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
982 index++) {
983 for (link = ha->dev[index].first; link !=
984 NULL; link = link->next) {
985 tq = link->base_address;
986 if (!VALID_DEVICE_ID(ha,
987 tq->loop_id)) {
988 continue;
989 }
990
991 if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
992 rval = ql_task_mgmt_iocb(ha,
993 tq, 0, CF_DO_NOT_SEND |
994 CF_TARGET_RESET, delay);
995 } else {
996 rval = ql_task_mgmt_iocb(ha,
997 tq, 0, CF_TARGET_RESET,
998 delay);
1029 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1030 mcp->mb[1] = tq->loop_id;
1031 } else {
1032 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1033 }
1034 mcp->mb[2] = delay;
1035 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1036 }
1037 mcp->in_mb = MBX_0;
1038 mcp->timeout = MAILBOX_TOV;
1039 rval = ql_mailbox_command(ha, mcp);
1040 }
1041
1042 tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1043 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1044
1045 if (rval != QL_SUCCESS) {
1046 EL(ha, "failed, rval = %xh\n", rval);
1047 } else {
1048 /*EMPTY*/
1049 QL_PRINT_3(ha, "done\n");
1050 }
1051
1052 return (rval);
1053 }
1054
1055 /*
1056 * ql_abort_target
1057 * Issue abort target mailbox command.
1058 *
1059 * Input:
1060 * ha: adapter state pointer.
1061 * tq: target queue pointer.
1062 * delay: in seconds.
1063 *
1064 * Returns:
1065 * ql local function return status code.
1066 *
1067 * Context:
1068 * Kernel context.
1069 */
1070 int
1071 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1072 {
1073 ql_srb_t *sp;
1074 uint16_t index;
1075 int rval;
1076 mbx_cmd_t mc = {0};
1077 mbx_cmd_t *mcp = &mc;
1078
1079 QL_PRINT_3(ha, "started\n");
1080
1081 ql_requeue_pending_cmds(ha, tq);
1082 INTR_LOCK(ha);
1083 for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1084 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1085 sp->lun_queue != NULL &&
1086 sp->lun_queue->target_queue == tq) {
1087 sp->flags |= SRB_ABORTING;
1088 }
1089 }
1090 INTR_UNLOCK(ha);
1091
1092 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1093 rval = ql_task_mgmt_iocb(ha, tq, 0,
1094 CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1095 } else {
1096 mcp->mb[0] = MBC_ABORT_TARGET;
1097 /* Don't send Task Mgt */
1098 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1099 mcp->mb[1] = tq->loop_id;
1100 mcp->mb[10] = BIT_0;
1101 mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1102 } else {
1103 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1104 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1105 }
1106 mcp->mb[2] = delay;
1107 mcp->in_mb = MBX_0;
1108 mcp->timeout = MAILBOX_TOV;
1109 rval = ql_mailbox_command(ha, mcp);
1110 }
1111
1112 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1113
1114 if (rval != QL_SUCCESS) {
1115 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1116 } else {
1117 /*EMPTY*/
1118 QL_PRINT_3(ha, "done\n");
1119 }
1120 return (rval);
1121 }
1122
1123 /*
1124 * ql_lun_reset
1125 * Issue LUN reset task management mailbox command.
1126 *
1127 * Input:
1128 * ha: adapter state pointer.
1129 * tq: target queue pointer.
1130 * lq: LUN queue pointer.
1131 *
1132 * Returns:
1133 * ql local function return status code.
1134 *
1135 * Context:
1136 * Kernel context.
1137 */
1138 int
1139 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1140 {
1141 ql_srb_t *sp;
1142 uint16_t index;
1143 int rval;
1144 mbx_cmd_t mc = {0};
1145 mbx_cmd_t *mcp = &mc;
1146
1147 QL_PRINT_3(ha, "started\n");
1148
1149 ql_requeue_pending_cmds(ha, tq);
1150 INTR_LOCK(ha);
1151 for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1152 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1153 sp->lun_queue != NULL &&
1154 sp->lun_queue->target_queue == tq &&
1155 sp->lun_queue == lq) {
1156 sp->flags |= SRB_ABORTING;
1157 }
1158 }
1159 INTR_UNLOCK(ha);
1160
1161 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1162 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1163 CF_LUN_RESET, 0);
1164 } else {
1165 mcp->mb[0] = MBC_LUN_RESET;
1166 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1167 mcp->mb[1] = tq->loop_id;
1168 } else {
1169 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1170 }
1171 mcp->mb[2] = lq->lun_no;
1172 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1173 mcp->in_mb = MBX_0;
1174 mcp->timeout = MAILBOX_TOV;
1175 rval = ql_mailbox_command(ha, mcp);
1176 }
1177
1178 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1179
1180 if (rval != QL_SUCCESS) {
1181 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1182 } else {
1183 /*EMPTY*/
1184 QL_PRINT_3(ha, "done\n");
1185 }
1186 return (rval);
1187 }
1188
1189 /*
1190 * ql_clear_task_set
1191 * Issue clear task set mailbox command.
1192 *
1193 * Input:
1194 * ha: adapter state pointer.
1195 * tq: target queue pointer.
1196 * lq: LUN queue pointer.
1197 *
1198 * Returns:
1199 * ql local function return status code.
1200 *
1201 * Context:
1202 * Kernel context.
1203 */
1204 int
1205 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1206 {
1207 ql_srb_t *sp;
1208 uint16_t index;
1209 int rval;
1210 mbx_cmd_t mc = {0};
1211 mbx_cmd_t *mcp = &mc;
1212
1213 QL_PRINT_3(ha, "started\n");
1214
1215 ql_requeue_pending_cmds(ha, tq);
1216 INTR_LOCK(ha);
1217 for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1218 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1219 sp->lun_queue != NULL &&
1220 sp->lun_queue->target_queue == tq &&
1221 sp->lun_queue == lq) {
1222 sp->flags |= SRB_ABORTING;
1223 }
1224 }
1225 INTR_UNLOCK(ha);
1226
1227 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1228 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1229 CF_CLEAR_TASK_SET, 0);
1230 } else {
1231 mcp->mb[0] = MBC_CLEAR_TASK_SET;
1232 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1233 mcp->mb[1] = tq->loop_id;
1234 } else {
1235 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1236 }
1237 mcp->mb[2] = lq->lun_no;
1238 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1239 mcp->in_mb = MBX_0;
1240 mcp->timeout = MAILBOX_TOV;
1241 rval = ql_mailbox_command(ha, mcp);
1242 }
1243
1244 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1245
1246 if (rval != QL_SUCCESS) {
1247 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1248 } else {
1249 /*EMPTY*/
1250 QL_PRINT_3(ha, "done\n");
1251 }
1252
1253 return (rval);
1254 }
1255
1256 /*
1257 * ql_abort_task_set
1258 * Issue abort task set mailbox command.
1259 *
1260 * Input:
1261 * ha: adapter state pointer.
1262 * tq: target queue pointer.
1263 * lq: LUN queue pointer.
1264 *
1265 * Returns:
1266 * ql local function return status code.
1267 *
1268 * Context:
1269 * Kernel context.
1270 */
1271 int
1272 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1273 {
1274 ql_srb_t *sp;
1275 uint16_t index;
1276 int rval;
1277 mbx_cmd_t mc = {0};
1278 mbx_cmd_t *mcp = &mc;
1279
1280 QL_PRINT_3(ha, "started\n");
1281
1282 ql_requeue_pending_cmds(ha, tq);
1283 INTR_LOCK(ha);
1284 for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1285 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1286 sp->lun_queue != NULL &&
1287 sp->lun_queue->target_queue == tq &&
1288 sp->lun_queue == lq) {
1289 sp->flags |= SRB_ABORTING;
1290 }
1291 }
1292 INTR_UNLOCK(ha);
1293
1294 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1295 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1296 CF_ABORT_TASK_SET, 0);
1297 } else {
1298 mcp->mb[0] = MBC_ABORT_TASK_SET;
1299 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1300 mcp->mb[1] = tq->loop_id;
1301 } else {
1302 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1303 }
1304 mcp->mb[2] = lq->lun_no;
1305 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1306 mcp->in_mb = MBX_0;
1307 mcp->timeout = MAILBOX_TOV;
1308 rval = ql_mailbox_command(ha, mcp);
1309 }
1310
1311 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1312
1313 if (rval != QL_SUCCESS) {
1314 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1315 } else {
1316 /*EMPTY*/
1317 QL_PRINT_3(ha, "done\n");
1318 }
1319
1320 return (rval);
1321 }
1322
1323 /*
1324 * ql_task_mgmt_iocb
1325 * Function issues task management IOCB.
1326 *
1327 * Input:
1328 * ha: adapter state pointer.
1329 * tq: target queue pointer.
1330 * lun_addr: LUN.
1331 * flags: control flags.
1332 * delay: seconds.
1333 *
1334 * Returns:
1335 * ql local function return status code.
1336 *
1337 * Context:
1338 * Kernel context
1339 */
1340 static int
1341 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint64_t lun_addr,
1342 uint32_t flags, uint16_t delay)
1343 {
1344 ql_mbx_iocb_t *pkt;
1345 int rval;
1346 uint32_t pkt_size;
1347 fcp_ent_addr_t *fcp_ent_addr;
1348
1349 QL_PRINT_3(ha, "started\n");
1350
1351 pkt_size = sizeof (ql_mbx_iocb_t);
1352 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1353 if (pkt == NULL) {
1354 EL(ha, "failed, kmem_zalloc\n");
1355 return (QL_MEMORY_ALLOC_FAILED);
1356 }
1357
1358 pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1359 pkt->mgmt.entry_count = 1;
1360
1361 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1362 pkt->mgmt.delay = (uint16_t)LE_16(delay);
1363 pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1364
1365 fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr;
1366 pkt->mgmt.fcp_lun[2] = lobyte(fcp_ent_addr->ent_addr_0);
1367 pkt->mgmt.fcp_lun[3] = hibyte(fcp_ent_addr->ent_addr_0);
1368 pkt->mgmt.fcp_lun[0] = lobyte(fcp_ent_addr->ent_addr_1);
1369 pkt->mgmt.fcp_lun[1] = hibyte(fcp_ent_addr->ent_addr_1);
1370 pkt->mgmt.fcp_lun[6] = lobyte(fcp_ent_addr->ent_addr_2);
1371 pkt->mgmt.fcp_lun[7] = hibyte(fcp_ent_addr->ent_addr_2);
1372 pkt->mgmt.fcp_lun[4] = lobyte(fcp_ent_addr->ent_addr_3);
1373 pkt->mgmt.fcp_lun[5] = hibyte(fcp_ent_addr->ent_addr_3);
1374
1375 pkt->mgmt.control_flags = LE_32(flags);
1376 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1377 pkt->mgmt.target_id[1] = tq->d_id.b.area;
1378 pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1379 pkt->mgmt.vp_index = ha->vp_index;
1380
1381 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1382 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1383 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1384 pkt->sts24.entry_status, tq->d_id.b24);
1385 rval = QL_FUNCTION_PARAMETER_ERROR;
1386 }
1387
1388 LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1389
1390 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1391 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1392 pkt->sts24.comp_status, tq->d_id.b24);
1393 rval = QL_FUNCTION_FAILED;
1394 }
1395
1396 kmem_free(pkt, pkt_size);
1397
1398 if (rval != QL_SUCCESS) {
1399 EL(ha, "failed, rval = %xh\n", rval);
1400 } else {
1401 /*EMPTY*/
1402 QL_PRINT_3(ha, "done\n");
1403 }
1404
1405 return (rval);
1406 }
1407
1408 /*
1409 * ql_loop_port_bypass
1410 * Issue loop port bypass mailbox command.
1411 *
1412 * Input:
1413 * ha: adapter state pointer.
1414 * tq: target queue pointer.
1415 *
1416 * Returns:
1417 * ql local function return status code.
1418 *
1419 * Context:
1420 * Kernel context.
1421 */
1422 int
1423 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1424 {
1425 int rval;
1426 mbx_cmd_t mc = {0};
1427 mbx_cmd_t *mcp = &mc;
1428
1429 QL_PRINT_3(ha, "started\n");
1430
1431 mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1432
1433 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1434 mcp->mb[1] = tq->d_id.b.al_pa;
1435 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1436 mcp->mb[1] = tq->loop_id;
1437 } else {
1438 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1439 }
1440
1441 mcp->out_mb = MBX_1|MBX_0;
1442 mcp->in_mb = MBX_0;
1443 mcp->timeout = MAILBOX_TOV;
1444 rval = ql_mailbox_command(ha, mcp);
1445
1446 if (rval != QL_SUCCESS) {
1447 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1448 } else {
1449 /*EMPTY*/
1450 QL_PRINT_3(ha, "done\n");
1451 }
1452
1453 return (rval);
1454 }
1455
1456 /*
1457 * ql_loop_port_enable
1458 * Issue loop port enable mailbox command.
1459 *
1460 * Input:
1461 * ha: adapter state pointer.
1462 * tq: target queue pointer.
1463 *
1464 * Returns:
1465 * ql local function return status code.
1466 *
1467 * Context:
1468 * Kernel context.
1469 */
1470 int
1471 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1472 {
1473 int rval;
1474 mbx_cmd_t mc = {0};
1475 mbx_cmd_t *mcp = &mc;
1476
1477 QL_PRINT_3(ha, "started\n");
1478
1479 mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1480
1481 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1482 mcp->mb[1] = tq->d_id.b.al_pa;
1483 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1484 mcp->mb[1] = tq->loop_id;
1485 } else {
1486 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1487 }
1488 mcp->out_mb = MBX_1|MBX_0;
1489 mcp->in_mb = MBX_0;
1490 mcp->timeout = MAILBOX_TOV;
1491 rval = ql_mailbox_command(ha, mcp);
1492
1493 if (rval != QL_SUCCESS) {
1494 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1495 } else {
1496 /*EMPTY*/
1497 QL_PRINT_3(ha, "done\n");
1498 }
1499
1500 return (rval);
1501 }
1502
1503 /*
1504 * ql_login_lport
1505 * Issue login loop port mailbox command.
1506 *
1507 * Input:
1508 * ha: adapter state pointer.
1509 * tq: target queue pointer.
1510 * loop_id: FC loop id.
1511 * opt: options.
1512 * LLF_NONE, LLF_PLOGI
1513 *
1514 * Returns:
1515 * ql local function return status code.
1516 *
1517 * Context:
1518 * Kernel context.
1519 */
1520 int
1521 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1522 uint16_t opt)
1523 {
1524 int rval;
1525 uint16_t flags;
1526 ql_mbx_data_t mr;
1527 mbx_cmd_t mc = {0};
1528 mbx_cmd_t *mcp = &mc;
1529
1530 QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1531 ha->instance, tq->d_id.b24, loop_id);
1532
1533 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1534 flags = CF_CMD_PLOGI;
1535 if ((opt & LLF_PLOGI) == 0) {
1536 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1537 }
1538 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1539 } else {
1540 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1541 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1542 mcp->mb[1] = loop_id;
1543 } else {
1544 mcp->mb[1] = (uint16_t)(loop_id << 8);
1545 }
1546 mcp->mb[2] = opt;
1547 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1548 mcp->in_mb = MBX_0;
1549 mcp->timeout = MAILBOX_TOV;
1550 rval = ql_mailbox_command(ha, mcp);
1551 }
1552
1553 if (rval != QL_SUCCESS) {
1554 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1555 loop_id, rval);
1556 } else {
1557 /*EMPTY*/
1558 QL_PRINT_3(ha, "done\n");
1559 }
1560
1561 return (rval);
1562 }
1563
1564 /*
1565 * ql_login_fport
1566 * Issue login fabric port mailbox command.
1567 *
1568 * Input:
1569 * ha: adapter state pointer.
1570 * tq: target queue pointer.
1571 * loop_id: FC loop id.
1572 * opt: options.
1573 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1574 * mr: pointer for mailbox data.
1575 *
1576 * Returns:
1577 * ql local function return status code.
1578 *
1579 * Context:
1580 * Kernel context.
1581 */
1582 int
1583 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1584 uint16_t opt, ql_mbx_data_t *mr)
1585 {
1586 int rval;
1587 uint16_t flags;
1588 mbx_cmd_t mc = {0};
1589 mbx_cmd_t *mcp = &mc;
1590
1591 QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1592 ha->instance, tq->d_id.b24, loop_id);
1593
1594 if ((tq->d_id.b24 & QL_PORT_ID_MASK) == FS_MANAGEMENT_SERVER) {
1595 opt = (uint16_t)(opt | LFF_NO_PRLI);
1596 }
1597
1598 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1599 flags = CF_CMD_PLOGI;
1600 if (opt & LFF_NO_PLOGI) {
1601 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1602 }
1603 if (opt & LFF_NO_PRLI) {
1604 flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1605 }
1606 rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1607 } else {
1608 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1609 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1610 mcp->mb[1] = loop_id;
1611 mcp->mb[10] = opt;
1612 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1613 } else {
1614 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1615 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1616 }
1617 mcp->mb[2] = MSW(tq->d_id.b24);
1618 mcp->mb[3] = LSW(tq->d_id.b24);
1619 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1620 mcp->timeout = MAILBOX_TOV;
1621 rval = ql_mailbox_command(ha, mcp);
1622
1623 /* Return mailbox data. */
1624 if (mr != NULL) {
1625 mr->mb[0] = mcp->mb[0];
1626 mr->mb[1] = mcp->mb[1];
1627 mr->mb[2] = mcp->mb[2];
1628 mr->mb[6] = mcp->mb[6];
1629 mr->mb[7] = mcp->mb[7];
1630 }
1631 }
1632
1633 if (rval != QL_SUCCESS) {
1634 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1635 "mb2=%04x\n", tq->d_id.b24, loop_id, rval,
1636 mr != NULL ? mr->mb[1] : mcp->mb[1],
1637 mr != NULL ? mr->mb[2] : mcp->mb[2]);
1638 } else {
1639 /*EMPTY*/
1640 QL_PRINT_3(ha, "done\n");
1641 }
1642
1643 return (rval);
1644 }
1645
1646 /*
1647 * ql_logout_fabric_port
1648 * Issue logout fabric port mailbox command.
1649 *
1650 * Input:
1651 * ha: adapter state pointer.
1652 * tq: target queue pointer.
1653 *
1654 * Returns:
1655 * ql local function return status code.
1656 *
1657 * Context:
1658 * Kernel context.
1659 */
1660 int
1661 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1662 {
1663 int rval;
1664 uint16_t flag;
1665 ql_mbx_data_t mr;
1666 mbx_cmd_t mc = {0};
1667 mbx_cmd_t *mcp = &mc;
1668
1669 QL_PRINT_3(ha, "started, loop_id=%xh d_id=%xh\n",
1670 tq->loop_id, tq->d_id.b24);
1671
1672 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1673 if ((ha->topology & QL_N_PORT) &&
1674 (tq->loop_id != 0x7fe) &&
1675 (tq->loop_id != 0x7ff)) {
1676 flag = (uint16_t)(CFO_IMPLICIT_LOGO |
1677 CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1678
1679 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1680 } else {
1681 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1682 CFO_EXPLICIT_LOGO | CF_CMD_LOGO |
1683 CFO_FREE_N_PORT_HANDLE :
1684 CFO_IMPLICIT_LOGO | CF_CMD_LOGO |
1685 CFO_FREE_N_PORT_HANDLE);
1686
1687 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1688 }
1689
1690 if (rval == QL_SUCCESS) {
1691 EL(ha, "tq=%ph, loop_id=%xh, d_id=%xh, flag=%xh\n",
1692 tq, tq->loop_id, tq->d_id.b24, flag);
1693 }
1694 } else {
1695 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0);
1696 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1697 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1698 mcp->mb[1] = tq->loop_id;
1699 mcp->mb[10] = flag;
1700 mcp->out_mb = MBX_10|MBX_1|MBX_0;
1701 } else {
1702 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1703 mcp->out_mb = MBX_1|MBX_0;
1704 }
1705 mcp->in_mb = MBX_0;
1706 mcp->timeout = MAILBOX_TOV;
1707 rval = ql_mailbox_command(ha, mcp);
1708 }
1709
1710 if (rval != QL_SUCCESS) {
1711 EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n", rval,
1712 tq->d_id.b24, tq->loop_id);
1713 } else {
1714 /*EMPTY*/
1715 QL_PRINT_3(ha, "done\n");
1716 }
1717
1718 return (rval);
1719 }
1720
1721 /*
1722 * ql_log_iocb
1723 * Function issues login/logout IOCB.
1724 *
1725 * Input:
1726 * ha: adapter state pointer.
1727 * tq: target queue pointer.
1728 * loop_id: FC Loop ID.
1729 * flags: control flags.
1730 * mr: pointer for mailbox data.
1731 *
1732 * Returns:
1733 * ql local function return status code.
1734 *
1735 * Context:
1736 * Kernel context.
1737 */
1738 int
1739 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1740 uint16_t flags, ql_mbx_data_t *mr)
1741 {
1742 ql_mbx_iocb_t *pkt;
1743 int rval;
1744 uint32_t pkt_size;
1745
1746 QL_PRINT_3(ha, "started\n");
1747
1748 pkt_size = sizeof (ql_mbx_iocb_t);
1749 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1750 if (pkt == NULL) {
1751 EL(ha, "failed, kmem_zalloc\n");
1752 return (QL_MEMORY_ALLOC_FAILED);
1753 }
1754
1755 pkt->log.entry_type = LOG_TYPE;
1756 pkt->log.entry_count = 1;
1757 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1758 pkt->log.control_flags = (uint16_t)LE_16(flags);
1759 pkt->log.port_id[0] = tq->d_id.b.al_pa;
1760 pkt->log.port_id[1] = tq->d_id.b.area;
1761 pkt->log.port_id[2] = tq->d_id.b.domain;
1762 pkt->log.vp_index = ha->vp_index;
1763
1764 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1765 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1766 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1851 mr->mb[0] = MBS_PORT_ID_USED;
1852 mr->mb[1] = LSW(pkt->log.io_param[1]);
1853 break;
1854 case CS0_N_PORT_HANDLE_USED:
1855 mr->mb[0] = MBS_LOOP_ID_USED;
1856 mr->mb[1] = MSW(pkt->log.io_param[1]);
1857 mr->mb[2] = LSW(pkt->log.io_param[1]);
1858 break;
1859 case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1860 mr->mb[0] = MBS_ALL_IDS_IN_USE;
1861 break;
1862 case CS0_CMD_PARAMETER_ERROR:
1863 default:
1864 EL(ha, "pkt->log iop[0]=%xh\n",
1865 pkt->log.io_param[0]);
1866 mr->mb[0] =
1867 MBS_COMMAND_PARAMETER_ERROR;
1868 break;
1869 }
1870 } else {
1871 QL_PRINT_3(ha, "status=%xh\n", pkt->log.status);
1872
1873 mr->mb[0] = MBS_COMMAND_COMPLETE;
1874 mr->mb[1] = (uint16_t)
1875 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1876 if (pkt->log.io_param[0] & BIT_8) {
1877 mr->mb[1] = (uint16_t)
1878 (mr->mb[1] | BIT_1);
1879 }
1880 }
1881 rval = mr->mb[0];
1882 }
1883
1884 }
1885
1886 kmem_free(pkt, pkt_size);
1887
1888 if (rval != QL_SUCCESS) {
1889 EL(ha, "failed, rval=%xh, d_id=%xh loop_id=%xh\n",
1890 rval, tq->d_id.b24, loop_id);
1891 } else {
1892 /*EMPTY*/
1893 QL_PRINT_3(ha, "done\n");
1894 }
1895
1896 return (rval);
1897 }
1898
1899 /*
1900 * ql_get_port_database
1901 * Issue get port database mailbox command
1902 * and copy context to device queue.
1903 *
1904 * Input:
1905 * ha: adapter state pointer.
1906 * tq: target queue pointer.
1907 * opt: options.
1908 * PDF_NONE, PDF_PLOGI, PDF_ADISC
1909 * Returns:
1910 * ql local function return status code.
1911 *
1912 * Context:
1913 * Kernel context.
1914 */
1915 int
1916 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1917 {
1918 int rval;
1919 dma_mem_t mem_desc;
1920 mbx_cmd_t mc = {0};
1921 mbx_cmd_t *mcp = &mc;
1922 port_database_23_t *pd23;
1923
1924 QL_PRINT_3(ha, "started\n");
1925
1926 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1927 if (pd23 == NULL) {
1928 rval = QL_MEMORY_ALLOC_FAILED;
1929 EL(ha, "failed, rval = %xh\n", rval);
1930 return (rval);
1931 }
1932
1933 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1934 PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1935 return (QL_MEMORY_ALLOC_FAILED);
1936 }
1937
1938 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1939 mcp->mb[0] = MBC_GET_PORT_DATABASE;
1940 mcp->mb[1] = tq->loop_id;
1941 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1942 mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1943 mcp->mb[9] = ha->vp_index;
1944 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1945 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1946 MBX_2|MBX_1|MBX_0;
1947 } else {
1948 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1949 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1950 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1951 mcp->mb[1] = tq->loop_id;
1952 mcp->mb[10] = opt;
1953 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1954 MBX_2|MBX_1|MBX_0;
1955 } else {
1956 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1957 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1958 }
1959 }
1960
1961 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1962 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1963 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1964 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1965 mcp->in_mb = MBX_0;
1966 mcp->timeout = MAILBOX_TOV;
1967 rval = ql_mailbox_command(ha, mcp);
1968
1969 if (rval == QL_SUCCESS) {
1970 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1971 }
1972
1973 ql_free_dma_resource(ha, &mem_desc);
1974
1975 if (rval == QL_SUCCESS) {
1976 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1977 port_database_24_t *pd24 = (port_database_24_t *)pd23;
1978
1979 tq->master_state = pd24->current_login_state;
1980 tq->slave_state = pd24->last_stable_login_state;
1981 if (PD_PORT_LOGIN(tq)) {
1982 /* Names are big endian. */
1983 bcopy((void *)&pd24->port_name[0],
1984 (void *)&tq->port_name[0], 8);
1985 bcopy((void *)&pd24->node_name[0],
1986 (void *)&tq->node_name[0], 8);
1987 tq->hard_addr.b.al_pa = pd24->hard_address[2];
1988 tq->hard_addr.b.area = pd24->hard_address[1];
1989 tq->hard_addr.b.domain = pd24->hard_address[0];
1990 tq->class3_rcv_data_size =
1991 pd24->receive_data_size;
1992 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1993 tq->prli_svc_param_word_0 =
1994 pd24->PRLI_service_parameter_word_0;
1995 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1996 tq->prli_svc_param_word_3 =
2048 rval = QL_NOT_LOGGED_IN;
2049 } else {
2050 tq->flags = tq->prli_svc_param_word_3 &
2051 PRLI_W3_TARGET_FUNCTION ?
2052 tq->flags & ~TQF_INITIATOR_DEVICE :
2053 tq->flags | TQF_INITIATOR_DEVICE;
2054
2055 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
2056 tq->flags = tq->prli_svc_param_word_3 &
2057 PRLI_W3_RETRY ?
2058 tq->flags | TQF_TAPE_DEVICE :
2059 tq->flags & ~TQF_TAPE_DEVICE;
2060 } else {
2061 tq->flags &= ~TQF_TAPE_DEVICE;
2062 }
2063 }
2064 }
2065
2066 kmem_free(pd23, PORT_DATABASE_SIZE);
2067
2068 /*
2069 * log the trace in any cases other than QL_SUCCESS.
2070 */
2071 if (rval != QL_SUCCESS) {
2072 EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n",
2073 rval, tq->d_id.b24, tq->loop_id);
2074 } else {
2075 /*EMPTY*/
2076 QL_PRINT_3(ha, "done\n");
2077 }
2078
2079 return (rval);
2080 }
2081
2082 /*
2083 * ql_get_loop_position_map
2084 * Issue get loop position map mailbox command.
2085 *
2086 * Input:
2087 * ha: adapter state pointer.
2088 * size: size of data buffer.
2089 * bufp: data pointer for DMA data.
2090 *
2091 * Returns:
2092 * ql local function return status code.
2093 *
2094 * Context:
2095 * Kernel context.
2096 */
2097 int
2098 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2099 {
2100 int rval;
2101 dma_mem_t mem_desc;
2102 mbx_cmd_t mc = {0};
2103 mbx_cmd_t *mcp = &mc;
2104
2105 QL_PRINT_3(ha, "started\n");
2106
2107 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2108 (uint32_t)size)) != QL_SUCCESS) {
2109 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2110 return (QL_MEMORY_ALLOC_FAILED);
2111 }
2112
2113 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2114 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2115 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2116 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2117 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2118 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2119 mcp->in_mb = MBX_1|MBX_0;
2120 mcp->timeout = MAILBOX_TOV;
2121 rval = ql_mailbox_command(ha, mcp);
2122
2123 if (rval == QL_SUCCESS) {
2124 ql_get_mbox_dma_data(&mem_desc, bufp);
2125 }
2126
2127 ql_free_dma_resource(ha, &mem_desc);
2128
2129 if (rval != QL_SUCCESS) {
2130 EL(ha, "failed=%xh\n", rval);
2131 } else {
2132 /*EMPTY*/
2133 QL_PRINT_3(ha, "done\n");
2134 }
2135
2136 return (rval);
2137 }
2138
2139 /*
2140 * ql_set_rnid_params
2141 * Issue set RNID parameters mailbox command.
2142 *
2143 * Input:
2144 * ha: adapter state pointer.
2145 * size: size of data buffer.
2146 * bufp: data pointer for DMA data.
2147 *
2148 * Returns:
2149 * ql local function return status code.
2150 *
2151 * Context:
2152 * Kernel context.
2153 */
2154 int
2155 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2156 {
2157 int rval;
2158 dma_mem_t mem_desc;
2159 mbx_cmd_t mc = {0};
2160 mbx_cmd_t *mcp = &mc;
2161
2162 QL_PRINT_3(ha, "started\n");
2163
2164 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2165 (uint32_t)size)) != QL_SUCCESS) {
2166 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2167 return (rval);
2168 }
2169
2170 mcp->mb[0] = MBC_SET_PARAMETERS;
2171 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2172 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2173 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2174 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2175 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2176 mcp->in_mb = MBX_0;
2177 mcp->timeout = MAILBOX_TOV;
2178 rval = ql_mailbox_command(ha, mcp);
2179
2180 ql_free_dma_resource(ha, &mem_desc);
2181
2182 if (rval != QL_SUCCESS) {
2183 EL(ha, "failed, rval = %xh\n", rval);
2184 } else {
2185 /*EMPTY*/
2186 QL_PRINT_3(ha, "done\n");
2187 }
2188
2189 return (rval);
2190 }
2191
2192 /*
2193 * ql_send_rnid_els
2194 * Issue a send node identfication data mailbox command.
2195 *
2196 * Input:
2197 * ha: adapter state pointer.
2198 * loop_id: FC loop id.
2199 * opt: options.
2200 * size: size of data buffer.
2201 * bufp: data pointer for DMA data.
2202 *
2203 * Returns:
2204 * ql local function return status code.
2205 *
2206 * Context:
2207 * Kernel context.
2208 */
2209 int
2210 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2211 size_t size, caddr_t bufp)
2212 {
2213 int rval;
2214 dma_mem_t mem_desc;
2215 mbx_cmd_t mc = {0};
2216 mbx_cmd_t *mcp = &mc;
2217
2218 QL_PRINT_3(ha, "started\n");
2219
2220 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2221 (uint32_t)size)) != QL_SUCCESS) {
2222 return (QL_MEMORY_ALLOC_FAILED);
2223 }
2224
2225 mcp->mb[0] = MBC_SEND_RNID_ELS;
2226 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2227 mcp->mb[1] = loop_id;
2228 mcp->mb[9] = ha->vp_index;
2229 mcp->mb[10] = opt;
2230 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2231 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2232 mcp->mb[1] = loop_id;
2233 mcp->mb[10] = opt;
2234 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2235 } else {
2236 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2237 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2238 }
2239 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2240 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2241 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2242 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2243 mcp->in_mb = MBX_0;
2244 mcp->timeout = MAILBOX_TOV;
2245 rval = ql_mailbox_command(ha, mcp);
2246
2247 if (rval == QL_SUCCESS) {
2248 ql_get_mbox_dma_data(&mem_desc, bufp);
2249 }
2250
2251 ql_free_dma_resource(ha, &mem_desc);
2252
2253 if (rval != QL_SUCCESS) {
2254 EL(ha, "failed, rval = %xh\n", rval);
2255 } else {
2256 /*EMPTY*/
2257 QL_PRINT_3(ha, "done\n");
2258 }
2259
2260 return (rval);
2261 }
2262
2263 /*
2264 * ql_get_rnid_params
2265 * Issue get RNID parameters mailbox command.
2266 *
2267 * Input:
2268 * ha: adapter state pointer.
2269 * size: size of data buffer.
2270 * bufp: data pointer for DMA data.
2271 *
2272 * Returns:
2273 * ql local function return status code.
2274 *
2275 * Context:
2276 * Kernel context.
2277 */
2278 int
2279 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2280 {
2281 int rval;
2282 dma_mem_t mem_desc;
2283 mbx_cmd_t mc = {0};
2284 mbx_cmd_t *mcp = &mc;
2285
2286 QL_PRINT_3(ha, "started\n");
2287
2288 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2289 (uint32_t)size)) != QL_SUCCESS) {
2290 return (QL_MEMORY_ALLOC_FAILED);
2291 }
2292
2293 mcp->mb[0] = MBC_GET_PARAMETERS;
2294 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2295 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2296 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2297 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2298 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2299 mcp->in_mb = MBX_0;
2300 mcp->timeout = MAILBOX_TOV;
2301 rval = ql_mailbox_command(ha, mcp);
2302
2303 if (rval == QL_SUCCESS) {
2304 ql_get_mbox_dma_data(&mem_desc, bufp);
2305 }
2306
2307 ql_free_dma_resource(ha, &mem_desc);
2308
2309 if (rval != QL_SUCCESS) {
2310 EL(ha, "failed=%xh\n", rval);
2311 } else {
2312 /*EMPTY*/
2313 QL_PRINT_3(ha, "done\n");
2314 }
2315
2316 return (rval);
2317 }
2318
2319 /*
2320 * ql_get_link_status
2321 * Issue get link status mailbox command.
2322 *
2323 * Input:
2324 * ha: adapter state pointer.
2325 * loop_id: FC loop id or n_port_hdl.
2326 * size: size of data buffer.
2327 * bufp: data pointer for DMA data.
2328 * port_no: port number to query.
2329 *
2330 * Returns:
2331 * ql local function return status code.
2332 *
2333 * Context:
2334 * Kernel context.
2335 */
2336 int
2337 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2338 caddr_t bufp, uint8_t port_no)
2339 {
2340 dma_mem_t mem_desc;
2341 mbx_cmd_t mc = {0};
2342 mbx_cmd_t *mcp = &mc;
2343 int rval = QL_SUCCESS;
2344 int retry = 0;
2345
2346 QL_PRINT_3(ha, "started\n");
2347
2348 do {
2349 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2350 (uint32_t)size)) != QL_SUCCESS) {
2351 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2352 return (QL_MEMORY_ALLOC_FAILED);
2353 }
2354
2355 mcp->mb[0] = MBC_GET_LINK_STATUS;
2356 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2357 if (loop_id == ha->loop_id) {
2358 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2359 mcp->mb[8] = (uint16_t)(size >> 2);
2360 mcp->out_mb = MBX_10|MBX_8;
2361 } else {
2362 mcp->mb[1] = loop_id;
2363 mcp->mb[4] = port_no;
2364 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2365 mcp->out_mb = MBX_10|MBX_4;
2366 }
2367 } else {
2368 if (retry) {
2369 port_no = (uint8_t)(port_no | BIT_3);
2370 }
2371 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2372 mcp->mb[1] = loop_id;
2373 mcp->mb[10] = port_no;
2374 mcp->out_mb = MBX_10;
2375 } else {
2376 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2392 ql_get_mbox_dma_data(&mem_desc, bufp);
2393 }
2394
2395 ql_free_dma_resource(ha, &mem_desc);
2396
2397 if (rval != QL_SUCCESS) {
2398 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2399 }
2400
2401 /*
2402 * Some of the devices want d_id in the payload,
2403 * strictly as per standard. Let's retry.
2404 */
2405
2406 } while (rval == QL_COMMAND_ERROR && !retry++);
2407
2408 if (rval != QL_SUCCESS) {
2409 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2410 } else {
2411 /*EMPTY*/
2412 QL_PRINT_3(ha, "done\n");
2413 }
2414
2415 return (rval);
2416 }
2417
2418 /*
2419 * ql_get_status_counts
2420 * Issue get adapter link status counts mailbox command.
2421 *
2422 * Input:
2423 * ha: adapter state pointer.
2424 * loop_id: FC loop id or n_port_hdl.
2425 * size: size of data buffer.
2426 * bufp: data pointer for DMA data.
2427 * port_no: port number to query.
2428 *
2429 * Returns:
2430 * ql local function return status code.
2431 *
2432 * Context:
2433 * Kernel context.
2434 */
2435 int
2436 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2437 caddr_t bufp, uint8_t port_no)
2438 {
2439 dma_mem_t mem_desc;
2440 mbx_cmd_t mc = {0};
2441 mbx_cmd_t *mcp = &mc;
2442 int rval = QL_SUCCESS;
2443
2444 QL_PRINT_3(ha, "started\n");
2445
2446 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2447 (uint32_t)size)) != QL_SUCCESS) {
2448 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2449 return (QL_MEMORY_ALLOC_FAILED);
2450 }
2451
2452 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2453 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2454 mcp->mb[8] = (uint16_t)(size / 4);
2455 mcp->out_mb = MBX_10|MBX_8;
2456 } else {
2457 mcp->mb[0] = MBC_GET_LINK_STATUS;
2458
2459 /* allows reporting when link is down */
2460 if (CFG_IST(ha, CFG_CTRL_22XX) == 0) {
2461 port_no = (uint8_t)(port_no | BIT_6);
2462 }
2463
2464 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2465 mcp->mb[1] = loop_id;
2466 mcp->mb[10] = port_no;
2467 mcp->out_mb = MBX_10|MBX_1;
2468 } else {
2469 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2470 port_no);
2471 mcp->out_mb = MBX_1;
2472 }
2473 }
2474 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2475 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2476 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2477 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2478 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2479 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2480 mcp->timeout = MAILBOX_TOV;
2481 rval = ql_mailbox_command(ha, mcp);
2482
2483 if (rval == QL_SUCCESS) {
2484 ql_get_mbox_dma_data(&mem_desc, bufp);
2485 }
2486
2487 ql_free_dma_resource(ha, &mem_desc);
2488
2489 if (rval != QL_SUCCESS) {
2490 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2491 mcp->mb[1], mcp->mb[2]);
2492 } else {
2493 /*EMPTY*/
2494 QL_PRINT_3(ha, "done\n");
2495 }
2496
2497 return (rval);
2498 }
2499
2500 /*
2501 * ql_reset_link_status
2502 * Issue Reset Link Error Status mailbox command
2503 *
2504 * Input:
2505 * ha: adapter state pointer.
2506 *
2507 * Returns:
2508 * ql local function return status code.
2509 *
2510 * Context:
2511 * Kernel context.
2512 */
2513 int
2514 ql_reset_link_status(ql_adapter_state_t *ha)
2515 {
2516 int rval;
2517 mbx_cmd_t mc = {0};
2518 mbx_cmd_t *mcp = &mc;
2519
2520 QL_PRINT_3(ha, "started\n");
2521
2522 mcp->mb[0] = MBC_RESET_LINK_STATUS;
2523 mcp->out_mb = MBX_0;
2524 mcp->in_mb = MBX_0;
2525 mcp->timeout = MAILBOX_TOV;
2526 rval = ql_mailbox_command(ha, mcp);
2527
2528 if (rval != QL_SUCCESS) {
2529 EL(ha, "failed=%xh\n", rval);
2530 } else {
2531 /*EMPTY*/
2532 QL_PRINT_3(ha, "done\n");
2533 }
2534
2535 return (rval);
2536 }
2537
2538 /*
2539 * ql_loop_reset
2540 * Issue loop reset.
2541 *
2542 * Input:
2543 * ha: adapter state pointer.
2544 *
2545 * Returns:
2546 * ql local function return status code.
2547 *
2548 * Context:
2549 * Kernel context.
2550 */
2551 int
2552 ql_loop_reset(ql_adapter_state_t *ha)
2553 {
2554 int rval;
2555
2556 QL_PRINT_3(ha, "started\n");
2557
2558 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2559 rval = ql_lip_reset(ha, 0xff);
2560 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2561 rval = ql_full_login_lip(ha);
2562 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2563 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2564 } else {
2565 rval = ql_initiate_lip(ha);
2566 }
2567
2568 if (rval != QL_SUCCESS) {
2569 EL(ha, "failed, rval = %xh\n", rval);
2570 } else {
2571 /*EMPTY*/
2572 QL_PRINT_3(ha, "done\n");
2573 }
2574
2575 return (rval);
2576 }
2577
2578 /*
2579 * ql_initiate_lip
2580 * Initiate LIP mailbox command.
2581 *
2582 * Input:
2583 * ha: adapter state pointer.
2584 *
2585 * Returns:
2586 * ql local function return status code.
2587 *
2588 * Context:
2589 * Kernel context.
2590 */
2591 int
2592 ql_initiate_lip(ql_adapter_state_t *ha)
2593 {
2594 int rval;
2595 mbx_cmd_t mc = {0};
2596 mbx_cmd_t *mcp = &mc;
2597
2598 QL_PRINT_3(ha, "started\n");
2599
2600 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2601 ql_toggle_loop_state(ha);
2602 QL_PRINT_3(ha, "8081 done\n");
2603 return (QL_SUCCESS);
2604 }
2605 if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2606 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2607 mcp->mb[1] = BIT_4;
2608 mcp->mb[3] = ha->loop_reset_delay;
2609 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2610 } else {
2611 mcp->mb[0] = MBC_INITIATE_LIP;
2612 mcp->out_mb = MBX_0;
2613 }
2614 mcp->in_mb = MBX_0;
2615 mcp->timeout = MAILBOX_TOV;
2616 rval = ql_mailbox_command(ha, mcp);
2617
2618 if (rval != QL_SUCCESS) {
2619 EL(ha, "failed, rval = %xh\n", rval);
2620 } else {
2621 /*EMPTY*/
2622 QL_PRINT_3(ha, "done\n");
2623 }
2624
2625 return (rval);
2626 }
2627
2628 /*
2629 * ql_full_login_lip
2630 * Issue full login LIP mailbox command.
2631 *
2632 * Input:
2633 * ha: adapter state pointer.
2634 *
2635 * Returns:
2636 * ql local function return status code.
2637 *
2638 * Context:
2639 * Kernel context.
2640 */
2641 int
2642 ql_full_login_lip(ql_adapter_state_t *ha)
2643 {
2644 int rval;
2645 mbx_cmd_t mc = {0};
2646 mbx_cmd_t *mcp = &mc;
2647
2648 QL_PRINT_3(ha, "started\n");
2649
2650 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2651 ql_toggle_loop_state(ha);
2652 QL_PRINT_3(ha, "8081 done\n");
2653 return (QL_SUCCESS);
2654 }
2655 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2656 if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2657 mcp->mb[1] = BIT_3;
2658 }
2659 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2660 mcp->in_mb = MBX_0;
2661 mcp->timeout = MAILBOX_TOV;
2662 rval = ql_mailbox_command(ha, mcp);
2663
2664 if (rval != QL_SUCCESS) {
2665 EL(ha, "failed, rval = %xh\n", rval);
2666 } else {
2667 /*EMPTY*/
2668 QL_PRINT_3(ha, "done");
2669 }
2670
2671 return (rval);
2672 }
2673
2674 /*
2675 * ql_lip_reset
2676 * Issue lip reset to a port.
2677 *
2678 * Input:
2679 * ha: adapter state pointer.
2680 * loop_id: FC loop id.
2681 *
2682 * Returns:
2683 * ql local function return status code.
2684 *
2685 * Context:
2686 * Kernel context.
2687 */
2688 int
2689 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2690 {
2691 int rval;
2692 mbx_cmd_t mc = {0};
2693 mbx_cmd_t *mcp = &mc;
2694
2695 QL_PRINT_3(ha, "started\n");
2696
2697 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2698 ql_toggle_loop_state(ha);
2699 QL_PRINT_3(ha, "8081 done\n");
2700 return (QL_SUCCESS);
2701 }
2702
2703 if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2704 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2705 mcp->mb[1] = BIT_6;
2706 mcp->mb[3] = ha->loop_reset_delay;
2707 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2708 } else {
2709 mcp->mb[0] = MBC_LIP_RESET;
2710 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2711 mcp->mb[1] = loop_id;
2712 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2713 } else {
2714 mcp->mb[1] = (uint16_t)(loop_id << 8);
2715 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2716 }
2717 mcp->mb[2] = ha->loop_reset_delay;
2718 }
2719 mcp->in_mb = MBX_0;
2720 mcp->timeout = MAILBOX_TOV;
2721 rval = ql_mailbox_command(ha, mcp);
2722
2723 if (rval != QL_SUCCESS) {
2724 EL(ha, "failed, rval = %xh\n", rval);
2725 } else {
2726 /*EMPTY*/
2727 QL_PRINT_3(ha, "done\n");
2728 }
2729
2730 return (rval);
2731 }
2732
2733 /*
2734 * ql_abort_command
2735 * Abort command aborts a specified IOCB.
2736 *
2737 * Input:
2738 * ha: adapter state pointer.
2739 * sp: SRB structure pointer.
2740 *
2741 * Returns:
2742 * ql local function return status code.
2743 *
2744 * Context:
2745 * Kernel context.
2746 */
2747 int
2748 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2749 {
2750 int rval;
2751 mbx_cmd_t mc = {0};
2752 mbx_cmd_t *mcp = &mc;
2753 ql_tgt_t *tq = sp->lun_queue->target_queue;
2754
2755 QL_PRINT_3(ha, "started\n");
2756
2757 sp->flags |= SRB_ABORTING;
2758 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2759 rval = ql_abort_cmd_iocb(ha, sp);
2760 } else {
2761 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2762 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2763 mcp->mb[1] = tq->loop_id;
2764 } else {
2765 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2766 }
2767 mcp->mb[2] = LSW(sp->handle);
2768 mcp->mb[3] = MSW(sp->handle);
2769 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2770 sp->lun_queue->lun_no : 0);
2771 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2772 mcp->in_mb = MBX_0;
2773 mcp->timeout = MAILBOX_TOV;
2774 rval = ql_mailbox_command(ha, mcp);
2775 }
2776
2777 if (rval != QL_SUCCESS) {
2778 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2779 tq->d_id.b24, sp->handle);
2780 } else {
2781 /*EMPTY*/
2782 QL_PRINT_3(ha, "done\n");
2783 }
2784
2785 return (rval);
2786 }
2787
2788 /*
2789 * ql_abort_cmd_iocb
2790 * Function issues abort command IOCB.
2791 *
2792 * Input:
2793 * ha: adapter state pointer.
2794 * sp: SRB structure pointer.
2795 *
2796 * Returns:
2797 * ql local function return status code.
2798 *
2799 * Context:
2800 * Interrupt or Kernel context, no mailbox commands allowed.
2801 */
2802 static int
2803 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2804 {
2805 ql_mbx_iocb_t *pkt;
2806 int rval;
2807 uint32_t pkt_size;
2808 uint16_t comp_status;
2809 ql_tgt_t *tq = sp->lun_queue->target_queue;
2810
2811 QL_PRINT_3(ha, "started\n");
2812
2813 pkt_size = sizeof (ql_mbx_iocb_t);
2814 if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2815 EL(ha, "failed, kmem_zalloc\n");
2816 return (QL_MEMORY_ALLOC_FAILED);
2817 }
2818
2819 pkt->abo.entry_type = ABORT_CMD_TYPE;
2820 pkt->abo.entry_count = 1;
2821 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2822 if (!CFG_IST(ha, CFG_CTRL_82XX)) {
2823 pkt->abo.options = AF_NO_ABTS;
2824 }
2825 pkt->abo.cmd_handle = LE_32(sp->handle);
2826 pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2827 pkt->abo.target_id[1] = tq->d_id.b.area;
2828 pkt->abo.target_id[2] = tq->d_id.b.domain;
2829 pkt->abo.vp_index = ha->vp_index;
2830
2831 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2832
2833 if (rval == QL_SUCCESS) {
2834 if ((pkt->abo.entry_status & 0x3c) != 0) {
2835 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2836 pkt->abo.entry_status, tq->d_id.b24);
2837 rval = QL_FUNCTION_PARAMETER_ERROR;
2838 } else {
2839 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2840 if (comp_status != CS_COMPLETE) {
2841 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2842 comp_status, tq->d_id.b24);
2843 rval = QL_FUNCTION_FAILED;
2844 }
2845 }
2846 }
2847
2848 kmem_free(pkt, pkt_size);
2849
2850 if (rval != QL_SUCCESS) {
2851 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2852 } else {
2853 /*EMPTY*/
2854 QL_PRINT_3(ha, "done\n");
2855 }
2856
2857 return (rval);
2858 }
2859
2860 /*
2861 * ql_verify_checksum
2862 * Verify loaded RISC firmware.
2863 *
2864 * Input:
2865 * ha = adapter state pointer.
2866 *
2867 * Returns:
2868 * ql local function return status code.
2869 *
2870 * Context:
2871 * Kernel context.
2872 */
2873 int
2874 ql_verify_checksum(ql_adapter_state_t *ha)
2875 {
2876 int rval;
2877 mbx_cmd_t mc = {0};
2878 mbx_cmd_t *mcp = &mc;
2879
2880 QL_PRINT_3(ha, "started\n");
2881
2882 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2883 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2884 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2885 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2886 } else {
2887 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2888 }
2889 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2890 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2891 mcp->timeout = MAILBOX_TOV;
2892 rval = ql_mailbox_command(ha, mcp);
2893
2894 if (rval != QL_SUCCESS) {
2895 EL(ha, "failed, rval = %xh\n", rval);
2896 } else {
2897 /*EMPTY*/
2898 QL_PRINT_3(ha, "done\n");
2899 }
2900
2901 return (rval);
2902 }
2903
2904 /*
2905 * ql_get_id_list
2906 * Get d_id and loop ID list.
2907 *
2908 * Input:
2909 * ha: adapter state pointer.
2910 * bp: data pointer for DMA data.
2911 * size: size of data buffer.
2912 * mr: pointer for mailbox data.
2913 *
2914 * Returns:
2915 * ql local function return status code.
2916 *
2917 * Context:
2918 * Kernel context.
2919 */
2920 int
2921 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2922 ql_mbx_data_t *mr)
2923 {
2924 int rval;
2925 dma_mem_t mem_desc;
2926 mbx_cmd_t mc = {0};
2927 mbx_cmd_t *mcp = &mc;
2928
2929 QL_PRINT_3(ha, "started\n");
2930
2931 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2932 (uint32_t)size)) != QL_SUCCESS) {
2933 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2934 return (QL_MEMORY_ALLOC_FAILED);
2935 }
2936
2937 mcp->mb[0] = MBC_GET_ID_LIST;
2938 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2939 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2940 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2941 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2942 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2943 mcp->mb[8] = (uint16_t)size;
2944 mcp->mb[9] = ha->vp_index;
2945 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2946 } else {
2947 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2948 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2949 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2950 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2951 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2952 }
2953 mcp->in_mb = MBX_1|MBX_0;
2954 mcp->timeout = MAILBOX_TOV;
2955 rval = ql_mailbox_command(ha, mcp);
2956
2957 if (rval == QL_SUCCESS) {
2958 ql_get_mbox_dma_data(&mem_desc, bp);
2959 }
2960
2961 ql_free_dma_resource(ha, &mem_desc);
2962
2963 /* Return mailbox data. */
2964 if (mr != NULL) {
2965 mr->mb[0] = mcp->mb[0];
2966 mr->mb[1] = mcp->mb[1];
2967 }
2968
2969 if (rval != QL_SUCCESS) {
2970 EL(ha, "failed, rval = %xh\n", rval);
2971 } else {
2972 /*EMPTY*/
2973 QL_PRINT_3(ha, "done\n");
2974 }
2975
2976 return (rval);
2977 }
2978
2979 /*
2980 * ql_wrt_risc_ram
2981 * Load RISC RAM.
2982 *
2983 * Input:
2984 * ha: adapter state pointer.
2985 * risc_address: risc ram word address.
2986 * bp: DMA pointer.
2987 * word_count: 16/32bit word count.
2988 *
2989 * Returns:
2990 * ql local function return status code.
2991 *
2992 * Context:
2993 * Kernel context.
2994 */
2995 int
2996 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2997 uint32_t word_count)
2998 {
2999 int rval;
3000 mbx_cmd_t mc = {0};
3001 mbx_cmd_t *mcp = &mc;
3002
3003 QL_PRINT_3(ha, "started\n");
3004
3005 mcp->mb[1] = LSW(risc_address);
3006 mcp->mb[2] = MSW(LSD(bp));
3007 mcp->mb[3] = LSW(LSD(bp));
3008 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3009 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
3010 mcp->mb[4] = MSW(word_count);
3011 mcp->mb[5] = LSW(word_count);
3012 mcp->mb[8] = MSW(risc_address);
3013 mcp->out_mb = MBX_0_THRU_8;
3014 } else {
3015 mcp->mb[0] = MBC_LOAD_RISC_RAM;
3016 mcp->mb[4] = LSW(word_count);
3017 mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3018 }
3019 mcp->mb[6] = MSW(MSD(bp));
3020 mcp->mb[7] = LSW(MSD(bp));
3021 mcp->in_mb = MBX_0;
3022 mcp->timeout = MAILBOX_TOV;
3023 rval = ql_mailbox_command(ha, mcp);
3024
3025 if (rval != QL_SUCCESS) {
3026 EL(ha, "failed, rval = %xh\n", rval);
3027 } else {
3028 /*EMPTY*/
3029 QL_PRINT_3(ha, "done\n");
3030 }
3031
3032 return (rval);
3033 }
3034
3035 /*
3036 * ql_rd_risc_ram
3037 * Get RISC RAM.
3038 *
3039 * Input:
3040 * ha: adapter state pointer.
3041 * risc_address: risc ram word address.
3042 * bp: direct data pointer.
3043 * word_count: 16/32bit word count.
3044 *
3045 * Returns:
3046 * ql local function return status code.
3047 *
3048 * Context:
3049 * Kernel context.
3050 */
3051 int
3052 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
3053 uint32_t word_count)
3054 {
3055 int rval;
3056 mbx_cmd_t mc = {0};
3057 mbx_cmd_t *mcp = &mc;
3058
3059 QL_PRINT_3(ha, "started\n");
3060
3061 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3062 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
3063 mcp->mb[1] = LSW(risc_address);
3064 mcp->mb[2] = MSW(LSD(bp));
3065 mcp->mb[3] = LSW(LSD(bp));
3066 mcp->mb[4] = MSW(word_count);
3067 mcp->mb[5] = LSW(word_count);
3068 mcp->mb[6] = MSW(MSD(bp));
3069 mcp->mb[7] = LSW(MSD(bp));
3070 mcp->mb[8] = MSW(risc_address);
3071 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
3072 MBX_0;
3073 } else {
3074 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */
3075 mcp->mb[1] = LSW(risc_address);
3076 mcp->mb[2] = MSW(LSD(bp));
3077 mcp->mb[3] = LSW(LSD(bp));
3078 mcp->mb[4] = LSW(word_count);
3079 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3080 }
3081 mcp->in_mb = MBX_0;
3082 mcp->timeout = MAILBOX_TOV;
3083 rval = ql_mailbox_command(ha, mcp);
3084
3085 if (rval != QL_SUCCESS) {
3086 EL(ha, "failed, rval = %xh\n", rval);
3087 } else {
3088 /*EMPTY*/
3089 QL_PRINT_3(ha, "done\n");
3090 }
3091
3092 return (rval);
3093 }
3094
3095 /*
3096 * ql_wrt_risc_ram_word
3097 * Write RISC RAM word.
3098 *
3099 * Input:
3100 * ha: adapter state pointer.
3101 * risc_address: risc ram word address.
3102 * data: data.
3103 *
3104 * Returns:
3105 * ql local function return status code.
3106 *
3107 * Context:
3108 * Kernel context.
3109 */
3110 int
3111 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3112 uint32_t data)
3113 {
3114 int rval;
3115 mbx_cmd_t mc = {0};
3116 mbx_cmd_t *mcp = &mc;
3117
3118 QL_PRINT_3(ha, "started\n");
3119
3120 mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3121 mcp->mb[1] = LSW(risc_address);
3122 mcp->mb[2] = LSW(data);
3123 mcp->mb[3] = MSW(data);
3124 mcp->mb[8] = MSW(risc_address);
3125 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3126 mcp->in_mb = MBX_0;
3127 mcp->timeout = MAILBOX_TOV;
3128
3129 rval = ql_mailbox_command(ha, mcp);
3130
3131 if (rval != QL_SUCCESS) {
3132 EL(ha, "failed, rval = %xh\n", rval);
3133 } else {
3134 /*EMPTY*/
3135 QL_PRINT_3(ha, "done\n");
3136 }
3137
3138 return (rval);
3139 }
3140
3141 /*
3142 * ql_rd_risc_ram_word
3143 * Read RISC RAM word.
3144 *
3145 * Input:
3146 * ha: adapter state pointer.
3147 * risc_address: risc ram word address.
3148 * data: data pointer.
3149 *
3150 * Returns:
3151 * ql local function return status code.
3152 *
3153 * Context:
3154 * Kernel context.
3155 */
3156 int
3157 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3158 uint32_t *data)
3159 {
3160 int rval;
3161 mbx_cmd_t mc = {0};
3162 mbx_cmd_t *mcp = &mc;
3163
3164 QL_PRINT_3(ha, "started\n");
3165
3166 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3167 mcp->mb[1] = LSW(risc_address);
3168 mcp->mb[8] = MSW(risc_address);
3169 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3170 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3171 mcp->timeout = MAILBOX_TOV;
3172
3173 rval = ql_mailbox_command(ha, mcp);
3174
3175 if (rval != QL_SUCCESS) {
3176 EL(ha, "failed, rval = %xh\n", rval);
3177 } else {
3178 *data = mcp->mb[2];
3179 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3180 *data |= mcp->mb[3] << 16;
3181 }
3182 QL_PRINT_3(ha, "done\n");
3183 }
3184
3185 return (rval);
3186 }
3187
3188 /*
3189 * ql_issue_mbx_iocb
3190 * Issue IOCB using mailbox command
3191 *
3192 * Input:
3193 * ha: adapter state pointer.
3194 * bp: buffer pointer.
3195 * size: buffer size.
3196 *
3197 * Returns:
3198 * ql local function return status code.
3199 *
3200 * Context:
3201 * Kernel context.
3202 */
3203 int
3204 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3205 {
3206 int rval;
3207 dma_mem_t mem_desc;
3208 mbx_cmd_t mc = {0};
3209 mbx_cmd_t *mcp = &mc;
3210
3211 QL_PRINT_3(ha, "started\n");
3212
3213 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3214 QL_SUCCESS) {
3215 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3216 return (rval);
3217 }
3218
3219 mcp->mb[0] = MBC_EXECUTE_IOCB;
3220 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3221 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3222 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3223 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3224 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3225 mcp->in_mb = MBX_1|MBX_0;
3226 mcp->timeout = MAILBOX_TOV + 5;
3227 rval = ql_mailbox_command(ha, mcp);
3228
3229 if (rval == QL_SUCCESS) {
3230 ql_get_mbox_dma_data(&mem_desc, bp);
3231 }
3232
3233 ql_free_dma_resource(ha, &mem_desc);
3234
3235 if (rval != QL_SUCCESS) {
3236 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3237 } else {
3238 /*EMPTY*/
3239 QL_PRINT_3(ha, "done\n");
3240 }
3241
3242 return (rval);
3243 }
3244
3245 /*
3246 * ql_mbx_wrap_test
3247 * Mailbox register wrap test.
3248 *
3249 * Input:
3250 * ha: adapter state pointer.
3251 * mr: pointer for in/out mailbox data.
3252 *
3253 * Returns:
3254 * ql local function return status code.
3255 *
3256 * Context:
3257 * Kernel context.
3258 */
3259 int
3260 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3261 {
3262 int rval;
3263 mbx_cmd_t mc = {0};
3264 mbx_cmd_t *mcp = &mc;
3265
3266 QL_PRINT_3(ha, "started cfg=0x%llx\n", ha->cfg_flags);
3267
3268 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3269 if (mr == NULL) {
3270 mcp->mb[1] = 0xAAAA;
3271 mcp->mb[2] = 0x5555;
3272 mcp->mb[3] = 0xAA55;
3273 mcp->mb[4] = 0x55AA;
3274 mcp->mb[5] = 0xA5A5;
3275 mcp->mb[6] = 0x5A5A;
3276 mcp->mb[7] = 0x2525;
3277 } else {
3278 mcp->mb[1] = mr->mb[1];
3279 mcp->mb[2] = mr->mb[2];
3280 mcp->mb[3] = mr->mb[3];
3281 mcp->mb[4] = mr->mb[4];
3282 mcp->mb[5] = mr->mb[5];
3283 mcp->mb[6] = mr->mb[6];
3284 mcp->mb[7] = mr->mb[7];
3285 }
3286 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3287 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3288 mcp->timeout = MAILBOX_TOV;
3289 rval = ql_mailbox_command(ha, mcp);
3290 if (rval == QL_SUCCESS) {
3291 if (mr == NULL) {
3292 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
3293 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) {
3294 rval = QL_FUNCTION_FAILED;
3295 }
3296 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
3297 mcp->mb[7] != 0x2525) {
3298 rval = QL_FUNCTION_FAILED;
3299 }
3300 } else {
3301 if (mcp->mb[1] != mr->mb[1] ||
3302 mcp->mb[2] != mr->mb[2] ||
3303 mcp->mb[3] != mr->mb[3] ||
3304 mcp->mb[4] != mr->mb[4]) {
3305 rval = QL_FUNCTION_FAILED;
3306 }
3307 if (mcp->mb[5] != mr->mb[5] ||
3308 mcp->mb[6] != mr->mb[6] ||
3309 mcp->mb[7] != mr->mb[7]) {
3310 rval = QL_FUNCTION_FAILED;
3311 }
3312 }
3313 }
3314
3315 if (rval != QL_SUCCESS) {
3316 EL(ha, "failed=%xh\n", rval);
3317 } else {
3318 /*EMPTY*/
3319 QL_PRINT_3(ha, "done\n");
3320 }
3321
3322 return (rval);
3323 }
3324
3325 /*
3326 * ql_execute_fw
3327 * Start adapter firmware.
3328 *
3329 * Input:
3330 * ha: adapter state pointer.
3331 *
3332 * Returns:
3333 * ql local function return status code.
3334 *
3335 * Context:
3336 * Kernel context.
3337 */
3338 int
3339 ql_execute_fw(ql_adapter_state_t *ha)
3340 {
3341 int rval;
3342 mbx_cmd_t mc = {0};
3343 mbx_cmd_t *mcp = &mc;
3344
3345 QL_PRINT_3(ha, "started\n");
3346
3347 if (CFG_IST(ha, CFG_CTRL_82XX)) {
3348 return (QL_SUCCESS);
3349 }
3350
3351 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3352 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3353 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3354 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3355 } else {
3356 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3357 }
3358 if (CFG_IST(ha, CFG_LR_SUPPORT)) {
3359 mcp->mb[4] = BIT_0;
3360 }
3361 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3362 mcp->in_mb = MBX_0;
3363 mcp->timeout = MAILBOX_TOV;
3364 rval = ql_mailbox_command(ha, mcp);
3365
3366 if (CFG_IST(ha, CFG_CTRL_22XX)) {
3367 rval = QL_SUCCESS;
3368 }
3369
3370 if (rval != QL_SUCCESS) {
3371 EL(ha, "failed=%xh\n", rval);
3372 } else {
3373 /*EMPTY*/
3374 QL_PRINT_3(ha, "done\n");
3375 }
3376
3377 return (rval);
3378 }
3379
3380 /*
3381 * ql_get_firmware_option
3382 * Get Firmware Options Mailbox Command.
3383 *
3384 * Input:
3385 * ha: adapter state pointer.
3386 * mr: pointer for mailbox data.
3387 *
3388 * Returns:
3389 * ql local function return status code.
3390 *
3391 * Context:
3392 * Kernel context.
3393 */
3394 int
3395 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3396 {
3397 int rval;
3398 mbx_cmd_t mc = {0};
3399 mbx_cmd_t *mcp = &mc;
3400
3401 QL_PRINT_3(ha, "started\n");
3402
3403 mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3404 mcp->out_mb = MBX_0;
3405 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3406 mcp->timeout = MAILBOX_TOV;
3407 rval = ql_mailbox_command(ha, mcp);
3408
3409 /* Return mailbox data. */
3410 if (mr != NULL) {
3411 mr->mb[0] = mcp->mb[0];
3412 mr->mb[1] = mcp->mb[1];
3413 mr->mb[2] = mcp->mb[2];
3414 mr->mb[3] = mcp->mb[3];
3415 }
3416
3417 if (rval != QL_SUCCESS) {
3418 EL(ha, "failed=%xh\n", rval);
3419 } else {
3420 /*EMPTY*/
3421 QL_PRINT_9(ha, "done\n");
3422 }
3423
3424 return (rval);
3425 }
3426
3427 /*
3428 * ql_set_firmware_option
3429 * Set Firmware Options Mailbox Command.
3430 *
3431 * Input:
3432 * ha: adapter state pointer.
3433 * mr: pointer for mailbox data.
3434 *
3435 * Returns:
3436 * ql local function return status code.
3437 *
3438 * Context:
3439 * Kernel context.
3440 */
3441 int
3442 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3443 {
3444 int rval;
3445 mbx_cmd_t mc = {0};
3446 mbx_cmd_t *mcp = &mc;
3447
3448 QL_PRINT_3(ha, "started\n");
3449
3450 if (mr != NULL) {
3451 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3452 mcp->mb[1] = mr->mb[1];
3453 mcp->mb[2] = mr->mb[2];
3454 mcp->mb[3] = mr->mb[3];
3455 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3456 mcp->in_mb = MBX_0;
3457 mcp->timeout = MAILBOX_TOV;
3458 rval = ql_mailbox_command(ha, mcp);
3459 } else {
3460 rval = QL_FUNCTION_PARAMETER_ERROR;
3461 }
3462
3463 if (rval != QL_SUCCESS) {
3464 EL(ha, "failed=%xh\n", rval);
3465 } else {
3466 /*EMPTY*/
3467 QL_PRINT_3(ha, "done\n");
3468 }
3469
3470 return (rval);
3471 }
3472
3473 /*
3474 * ql_init_firmware
3475 * Initialize firmware mailbox command.
3476 *
3477 * Input:
3478 * ha: adapter state pointer.
3479 * ha->init_ctrl_blk = setup for transmit.
3480 *
3481 * Returns:
3482 * ql local function return status code.
3483 *
3484 * Context:
3485 * Kernel context.
3486 */
3487 int
3488 ql_init_firmware(ql_adapter_state_t *ha)
3489 {
3490 int rval;
3491 dma_mem_t mem_desc;
3492 mbx_cmd_t mc = {0};
3493 mbx_cmd_t *mcp = &mc;
3494
3495 QL_PRINT_3(ha, "started\n");
3496
3497 if (ha->flags & MULTI_QUEUE) {
3498 WR32_MBAR_REG(ha, ha->req_q[0]->mbar_req_in, 0);
3499 WR32_MBAR_REG(ha, ha->rsp_queues[0]->mbar_rsp_out, 0);
3500 } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
3501 ql_8021_wr_req_in(ha, 0);
3502 WRT32_IO_REG(ha, req_out, 0);
3503 WRT32_IO_REG(ha, resp_in, 0);
3504 WRT32_IO_REG(ha, resp_out, 0);
3505 } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3506 WRT32_IO_REG(ha, req_in, 0);
3507 WRT32_IO_REG(ha, resp_out, 0);
3508 WRT32_IO_REG(ha, pri_req_in, 0);
3509 WRT32_IO_REG(ha, atio_req_out, 0);
3510 } else {
3511 WRT16_IO_REG(ha, req_in, 0);
3512 WRT16_IO_REG(ha, resp_out, 0);
3513 }
3514 if (ha->req_q[0]->req_out_shadow_ptr) {
3515 *ha->req_q[0]->req_out_shadow_ptr = 0;
3516 }
3517 if (ha->rsp_queues[0]->rsp_in_shadow_ptr) {
3518 *ha->rsp_queues[0]->rsp_in_shadow_ptr = 0;
3519 }
3520
3521 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3522 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3523 QL_SUCCESS) {
3524 EL(ha, "dma setup failed=%xh\n", rval);
3525 return (rval);
3526 }
3527
3528 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3529 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3530
3531 if (CFG_IST(ha, CFG_SBUS_CARD)) {
3532 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_22XX) ?
3533 0x204c : 0x52);
3534 }
3535
3536 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3537 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3538 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3539 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3540 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
3541 uint64_t ofst, addr;
3542 ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *)
3543 &ha->init_ctrl_blk.cb24;
3544
3545 mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW;
3546 if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) {
3547 ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb;
3548 addr = mem_desc.cookie.dmac_laddress + ofst;
3549 mcp->mb[10] = MSW(LSD(addr));
3550 mcp->mb[11] = LSW(LSD(addr));
3551 mcp->mb[12] = MSW(MSD(addr));
3552 mcp->mb[13] = LSW(MSD(addr));
3553 mcp->mb[14] = sizeof (ql_ext_icb_8100_t);
3554 mcp->mb[1] = BIT_0;
3555 }
3556 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
3557 MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3558 } else {
3559 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3560 }
3561 mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0;
3562 mcp->timeout = MAILBOX_TOV;
3563 rval = ql_mailbox_command(ha, mcp);
3564
3565 if (rval == QL_SUCCESS) {
3566 ha->sfp_stat = mcp->mb[2];
3567 if (CFG_IST(ha, CFG_CTRL_82XX)) {
3568 (void) ql_8021_get_md_template(ha);
3569 } else {
3570 uint16_t i, opt;
3571
3572 opt = ha->flags & NO_INTR_HANDSHAKE ?
3573 IMO_NONE : IMO_INTERRUPT_HANDSHAKE;
3574 if (ha->flags & QUEUE_SHADOW_PTRS) {
3575 opt |= IMO_QUEUE_POINTER_SHADOWING;
3576 }
3577 /* Initialize ha multi-response-queue request queue */
3578 if (ha->rsp_queues_cnt > 1) {
3579 rval = ql_init_req_q(ha, ha->req_q[1], opt);
3580 if (rval != QL_SUCCESS) {
3581 EL(ha, "ql_init_req_q=%xh\n", rval);
3582 return (rval);
3583 }
3584 }
3585 /* Initialize multi-response queues */
3586 for (i = 1; i < ha->rsp_queues_cnt; i++) {
3587 rval = ql_init_rsp_q(ha, ha->rsp_queues[i],
3588 opt);
3589 if (rval != QL_SUCCESS) {
3590 EL(ha, "ql_init_rsp_q=%xh\n", rval);
3591 return (rval);
3592 }
3593 }
3594 }
3595 }
3596 ql_free_dma_resource(ha, &mem_desc);
3597
3598 if (rval != QL_SUCCESS) {
3599 EL(ha, "failed=%xh\n", rval);
3600 } else {
3601 /*EMPTY*/
3602 QL_PRINT_3(ha, "done\n");
3603 }
3604
3605 return (rval);
3606 }
3607
3608 /*
3609 * ql_get_firmware_state
3610 * Get adapter firmware state.
3611 *
3612 * Input:
3613 * ha: adapter state pointer.
3614 * mr: pointer for mailbox data.
3615 *
3616 * Returns:
3617 * ql local function return status code.
3618 *
3619 * Context:
3620 * Kernel context.
3621 */
3622 int
3623 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3624 {
3625 int rval;
3626 mbx_cmd_t mc = {0};
3627 mbx_cmd_t *mcp = &mc;
3628
3629 QL_PRINT_3(ha, "started\n");
3630
3631 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3632 mcp->out_mb = MBX_0;
3633 mcp->in_mb = MBX_0_THRU_6;
3634 mcp->timeout = MAILBOX_TOV;
3635 rval = ql_mailbox_command(ha, mcp);
3636
3637 ha->fw_state[0] = mcp->mb[0];
3638 ha->fw_state[1] = mcp->mb[1];
3639 ha->fw_state[2] = mcp->mb[2];
3640 ha->fw_state[3] = mcp->mb[3];
3641 ha->fw_state[4] = mcp->mb[4];
3642 ha->fw_state[5] = mcp->mb[5];
3643 ha->fw_state[6] = mcp->mb[6];
3644
3645 /* Return mailbox data. */
3646 if (mr != NULL) {
3647 mr->mb[1] = mcp->mb[1];
3648 mr->mb[2] = mcp->mb[2];
3649 mr->mb[3] = mcp->mb[3];
3650 mr->mb[4] = mcp->mb[4];
3651 mr->mb[5] = mcp->mb[5];
3652 mr->mb[6] = mcp->mb[6];
3653 }
3654
3655 ha->sfp_stat = mcp->mb[2];
3656
3657 if (rval != QL_SUCCESS) {
3658 EL(ha, "failed=%xh\n", rval);
3659 } else {
3660 /*EMPTY*/
3661 QL_PRINT_3(ha, "done\n");
3662 }
3663
3664 return (rval);
3665 }
3666
3667 /*
3668 * ql_get_adapter_id
3669 * Get adapter ID and topology.
3670 *
3671 * Input:
3672 * ha: adapter state pointer.
3673 * mr: pointer for mailbox data.
3674 *
3675 * Returns:
3676 * ql local function return status code.
3677 *
3678 * Context:
3679 * Kernel context.
3680 */
3681 int
3682 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3683 {
3684 int i, rval;
3685 mbx_cmd_t mc = {0};
3686 mbx_cmd_t *mcp = &mc;
3687
3688 QL_PRINT_3(ha, "started\n");
3689
3690 mcp->mb[0] = MBC_GET_ID;
3691 if (ha->flags & VP_ENABLED) {
3692 mcp->mb[9] = ha->vp_index;
3693 }
3694 mcp->out_mb = MBX_9|MBX_0;
3695 mcp->in_mb = MBX_0_THRU_19;
3696 mcp->timeout = MAILBOX_TOV;
3697
3698 rval = ql_mailbox_command(ha, mcp);
3699
3700 /* Return mailbox data. */
3701 if (mr != NULL) {
3702 for (i = 0; i < 20; i++) {
3703 mr->mb[i] = mcp->mb[i];
3704 }
3705 }
3706
3707 if (rval != QL_SUCCESS) {
3708 EL(ha, "failed=%xh\n", rval);
3709 } else {
3710 /*EMPTY*/
3711 QL_PRINT_3(ha, "done\n");
3712 }
3713
3714 return (rval);
3715 }
3716
3717 /*
3718 * ql_get_fw_version
3719 * Get firmware version.
3720 *
3721 * Input:
3722 * ha: adapter state pointer.
3723 * mr: pointer for mailbox data.
3724 *
3725 * Returns:
3726 * ql local function return status code.
3727 *
3728 * Context:
3729 * Kernel context.
3730 */
3731 int
3732 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout)
3733 {
3734 int rval, i;
3735 mbx_cmd_t mc = {0};
3736 mbx_cmd_t *mcp = &mc;
3737
3738 QL_PRINT_3(ha, "started\n");
3739
3740 mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3741 mcp->out_mb = MBX_0;
3742 if (CFG_IST(ha, CFG_CTRL_83XX)) {
3743 mcp->in_mb = MBX_0_THRU_17;
3744 } else if (CFG_IST(ha, CFG_CTRL_27XX)) {
3745 mcp->in_mb = MBX_0_THRU_25;
3746 } else {
3747 mcp->in_mb = MBX_0_THRU_13;
3748 }
3749 mcp->timeout = timeout;
3750 rval = ql_mailbox_command(ha, mcp);
3751
3752 /* Return mailbox data. */
3753 if (mr != NULL) {
3754 for (i = 0; i < ha->reg_off->mbox_cnt && mcp->in_mb; i++) {
3755 if (mcp->in_mb & MBX_0) {
3756 mr->mb[i] = mcp->mb[i];
3757 }
3758 mcp->in_mb >>= 1;
3759 }
3760 }
3761
3762 if (rval != QL_SUCCESS) {
3763 EL(ha, "failed=%xh\n", rval);
3764 } else {
3765 /*EMPTY*/
3766 QL_PRINT_3(ha, "done\n");
3767 }
3768
3769 return (rval);
3770 }
3771
3772 /*
3773 * ql_data_rate
3774 * Issue data rate Mailbox Command.
3775 *
3776 * Input:
3777 * ha: adapter state pointer.
3778 * mr: pointer for mailbox data.
3779 *
3780 * Returns:
3781 * ql local function return status code.
3782 *
3783 * Context:
3784 * Kernel context.
3785 */
3786 int
3787 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3788 {
3789 int rval;
3790 mbx_cmd_t mc = {0};
3791 mbx_cmd_t *mcp = &mc;
3792
3793 QL_PRINT_3(ha, "started\n");
3794
3795 if (mr != NULL) {
3796 mcp->mb[0] = MBC_DATA_RATE;
3797 mcp->mb[1] = mr->mb[1];
3798 mcp->mb[2] = mr->mb[2];
3799 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3800 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3801 mcp->timeout = MAILBOX_TOV;
3802 rval = ql_mailbox_command(ha, mcp);
3803
3804 /* Return mailbox data. */
3805 mr->mb[1] = mcp->mb[1];
3806 mr->mb[2] = mcp->mb[2];
3807 mr->mb[3] = mcp->mb[3];
3808 } else {
3809 rval = QL_FUNCTION_PARAMETER_ERROR;
3810 }
3811
3812 ha->sfp_stat = mcp->mb[2];
3813
3814 if (rval != QL_SUCCESS) {
3815 EL(ha, "failed=%xh\n", rval);
3816 } else {
3817 /*EMPTY*/
3818 QL_PRINT_3(ha, "done\n");
3819 }
3820
3821 return (rval);
3822 }
3823
3824 /*
3825 * ql_Diag_Loopback
3826 * Issue Reset Link Status mailbox command
3827 *
3828 * Input:
3829 * ha: adapter state pointer.
3830 * bp: buffer pointer.
3831 * size: buffer size.
3832 * opt: command options.
3833 * it_cnt: iteration count.
3834 * mr: pointer for mailbox data.
3835 *
3836 * Returns:
3837 * ql local function return status code.
3838 *
3839 * Context:
3840 * Kernel context.
3841 */
3842 int
3843 ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
3844 uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3845 {
3846 int rval;
3847 dma_mem_t mem_desc;
3848 mbx_cmd_t mc = {0};
3849 mbx_cmd_t *mcp = &mc;
3850
3851 QL_PRINT_3(ha, "started\n");
3852
3853 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3854 QL_SUCCESS) {
3855 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3856 return (rval);
3857 }
3858
3859 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3860 mcp->mb[1] = opt;
3861 mcp->mb[2] = ha->fcoe_fcf_idx;
3862 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3863 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3864 mcp->mb[10] = LSW(size);
3865 mcp->mb[11] = MSW(size);
3866 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3867 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3868 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3869 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3870 mcp->mb[18] = LSW(it_cnt);
3871 mcp->mb[19] = MSW(it_cnt);
3872 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3873 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3874 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3875 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3876 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3877 mcp->timeout = it_cnt / 300;
3878 if (mcp->timeout < MAILBOX_TOV) {
3879 mcp->timeout = MAILBOX_TOV;
3880 }
3881 rval = ql_mailbox_command(ha, mcp);
3883 if (rval == QL_SUCCESS) {
3884 ql_get_mbox_dma_data(&mem_desc, bp);
3885 }
3886
3887 ql_free_dma_resource(ha, &mem_desc);
3888
3889 /* Return mailbox data. */
3890 if (mr != NULL) {
3891 mr->mb[0] = mcp->mb[0];
3892 mr->mb[1] = mcp->mb[1];
3893 mr->mb[2] = mcp->mb[2];
3894 mr->mb[3] = mcp->mb[3];
3895 mr->mb[18] = mcp->mb[18];
3896 mr->mb[19] = mcp->mb[19];
3897 }
3898
3899 if (rval != QL_SUCCESS) {
3900 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3901 } else {
3902 /*EMPTY*/
3903 QL_PRINT_3(ha, "done\n");
3904 }
3905
3906 return (rval);
3907 }
3908
3909 /*
3910 * ql_diag_echo
3911 * Issue Diag echo mailbox command. Valid for qla23xx HBA's.
3912 *
3913 * Input:
3914 * ha: adapter state pointer.
3915 * bp: buffer pointer.
3916 * size: buffer size.
3917 * opt: command options.
3918 * mr: pointer to mailbox status.
3919 *
3920 * Returns:
3921 * ql local function return status code.
3922 *
3923 * Context:
3924 * Kernel context.
3925 */
3926 int
3927 ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt,
3928 ql_mbx_data_t *mr)
3929 {
3930 int rval;
3931 dma_mem_t mem_desc;
3932 mbx_cmd_t mc = {0};
3933 mbx_cmd_t *mcp = &mc;
3934
3935 QL_PRINT_3(ha, "started\n");
3936
3937 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3938 QL_SUCCESS) {
3939 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3940 return (rval);
3941 }
3942
3943 mcp->mb[0] = MBC_ECHO;
3944 mcp->mb[1] = opt;
3945 mcp->mb[2] = ha->fcoe_fcf_idx;
3946 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3947 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3948 mcp->mb[10] = LSW(size);
3949 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3950 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3951 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3952 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3953 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3954 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3955 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3956 MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3957 mcp->in_mb = MBX_1|MBX_0;
3958 mcp->timeout = MAILBOX_TOV;
3959 rval = ql_mailbox_command(ha, mcp);
3960
3961 if (rval == QL_SUCCESS) {
3962 ql_get_mbox_dma_data(&mem_desc, bp);
3963 }
3964
3965 ql_free_dma_resource(ha, &mem_desc);
3966
3967 if (mr != NULL) {
3968 mr->mb[0] = mcp->mb[0];
3969 }
3970
3971 if (rval != QL_SUCCESS) {
3972 EL(ha, "failed=%xh, mb1=%xh\n", rval,
3973 mcp->mb[1]);
3974 } else {
3975 /*EMPTY*/
3976 QL_PRINT_3(ha, "done\n");
3977 }
3978
3979 return (rval);
3980 }
3981
3982 /*
3983 * ql_diag_beacon
3984 * Enable/Disable beaconing via mailbox command.
3985 *
3986 * Input:
3987 * ha: adapter state pointer.
3988 * mr: pointer to mailbox in/out parameters.
3989 *
3990 * Returns:
3991 * ql local function return status code.
3992 *
3993 * Context:
3994 * Kernel context.
3995 */
3996 int
3997 ql_diag_beacon(ql_adapter_state_t *ha, int cmd, ql_mbx_data_t *mr)
3998 {
3999 int rval;
4000 mbx_cmd_t mc = {0};
4001 mbx_cmd_t *mcp = &mc;
4002
4003 mcp->mb[0] = MBC_SET_LED_CONFIG;
4004 if (cmd == QL_BEACON_ENABLE) {
4005 mcp->mb[7] = 0xE;
4006 } else if (cmd == QL_BEACON_DISABLE) {
4007 mcp->mb[7] = 0xD;
4008 } else {
4009 return (EIO);
4010 }
4011 mcp->out_mb = MBX_7|MBX_0;
4012 mcp->in_mb = MBX_0;
4013 mcp->timeout = MAILBOX_TOV;
4014
4015 rval = ql_mailbox_command(ha, mcp);
4016
4017 /* Return mailbox data. */
4018 if (mr != NULL) {
4019 mr->mb[0] = mcp->mb[0];
4020 }
4021
4022 if (rval != QL_SUCCESS) {
4023 EL(ha, "failed=%xh\n", rval);
4024 }
4025
4026 return (rval);
4027 }
4028
4029
4030 /*
4031 * ql_serdes_param
4032 * Set/Get serdes transmit parameters mailbox command.
4033 *
4034 * Input:
4035 * ha: adapter state pointer.
4036 * mr: pointer to mailbox in/out parameters.
4037 *
4038 * Returns:
4039 * ql local function return status code.
4040 *
4041 * Context:
4042 * Kernel context.
4043 */
4044 int
4045 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4046 {
4047 int rval;
4048 mbx_cmd_t mc = {0};
4049 mbx_cmd_t *mcp = &mc;
4050
4051 QL_PRINT_3(ha, "started\n");
4052
4053 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
4054 mcp->mb[1] = mr->mb[1];
4055 mcp->mb[2] = mr->mb[2];
4056 mcp->mb[3] = mr->mb[3];
4057 mcp->mb[4] = mr->mb[4];
4058 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4059 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
4060 mcp->timeout = MAILBOX_TOV;
4061 rval = ql_mailbox_command(ha, mcp);
4062
4063 /* Return mailbox data. */
4064 mr->mb[0] = mcp->mb[0];
4065 mr->mb[2] = mcp->mb[2];
4066 mr->mb[3] = mcp->mb[3];
4067 mr->mb[4] = mcp->mb[4];
4068
4069 if (rval != QL_SUCCESS) {
4070 EL(ha, "failed=%xh\n", rval);
4071 } else {
4072 /*EMPTY*/
4073 QL_PRINT_3(ha, "done\n");
4074 }
4075
4076 return (rval);
4077 }
4078
4079 /*
4080 * ql_get_timeout_parameters
4081 * Issue get timeout parameters mailbox command.
4082 *
4083 * Input:
4084 * ha: adapter state pointer.
4085 * mr: pointer to mailbox in/out parameters.
4086 *
4087 * Returns:
4088 * ql local function return status code.
4089 *
4090 * Context:
4091 * Kernel context.
4092 */
4093 int
4094 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
4095 {
4096 int rval;
4097 mbx_cmd_t mc = {0};
4098 mbx_cmd_t *mcp = &mc;
4099
4100 QL_PRINT_3(ha, "started\n");
4101
4102 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
4103 mcp->mb[1] = ha->fcoe_fcf_idx;
4104 mcp->out_mb = MBX_1|MBX_0;
4105 mcp->in_mb = MBX_3|MBX_0;
4106 mcp->timeout = MAILBOX_TOV;
4107 rval = ql_mailbox_command(ha, mcp);
4108 if (rval == QL_SUCCESS) {
4109 /* Get 2 * R_A_TOV in seconds */
4110 if (CFG_IST(ha, CFG_CTRL_22XX) || mcp->mb[3] == 0) {
4111 *tov = R_A_TOV_DEFAULT;
4112 } else {
4113 *tov = (uint16_t)(mcp->mb[3] / 10);
4114 if (mcp->mb[3] % 10 != 0) {
4115 *tov = (uint16_t)(*tov + 1);
4116 }
4117 /*
4118 * Adjust value to prevent driver timeout at the same
4119 * time as device.
4120 */
4121 *tov = (uint16_t)(*tov + 5);
4122 }
4123 } else {
4124 *tov = R_A_TOV_DEFAULT;
4125 }
4126
4127 if (rval != QL_SUCCESS) {
4128 EL(ha, "failed=%xh\n", rval);
4129 } else {
4130 /*EMPTY*/
4131 QL_PRINT_3(ha, "done\n");
4132 }
4133
4134 return (rval);
4135 }
4136
4137 /*
4138 * ql_stop_firmware
4139 * Issue stop firmware Mailbox Command.
4140 *
4141 * Input:
4142 * ha: adapter state pointer.
4143 *
4144 * Returns:
4145 * ql local function return status code.
4146 *
4147 * Context:
4148 * Kernel context.
4149 */
4150 int
4151 ql_stop_firmware(ql_adapter_state_t *ha)
4152 {
4153 int rval;
4154 mbx_cmd_t mc = {0};
4155 mbx_cmd_t *mcp = &mc;
4156
4157 QL_PRINT_3(ha, "started\n");
4158
4159 mcp->mb[0] = MBC_STOP_FIRMWARE;
4160 mcp->out_mb = MBX_1|MBX_0;
4161 mcp->in_mb = MBX_0;
4162 mcp->timeout = 2;
4163 rval = ql_mailbox_command(ha, mcp);
4164
4165 if (rval != QL_SUCCESS) {
4166 EL(ha, "failed=%xh\n", rval);
4167 } else {
4168 /*EMPTY*/
4169 QL_PRINT_3(ha, "done\n");
4170 }
4171
4172 return (rval);
4173 }
4174
4175 /*
4176 * ql_read_sfp
4177 * Issue Read SFP Mailbox command
4178 *
4179 * Input:
4180 * ha: adapter state pointer.
4181 * mem: pointer to dma memory object for command.
4182 * dev: Device address (A0h or A2h).
4183 * addr: Data address on SFP EEPROM (0-255).
4184 *
4185 * Returns:
4186 * ql local function return status code.
4187 *
4188 * Context:
4189 * Kernel context.
4190 */
4191 int
4192 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
4193 uint16_t addr)
4194 {
4195 int rval;
4196 mbx_cmd_t mc = {0};
4197 mbx_cmd_t *mcp = &mc;
4198
4199 QL_PRINT_3(ha, "started\n");
4200
4201 mcp->mb[0] = MBC_READ_SFP;
4202 mcp->mb[1] = dev;
4203 mcp->mb[2] = MSW(mem->cookies->dmac_address);
4204 mcp->mb[3] = LSW(mem->cookies->dmac_address);
4205 mcp->mb[6] = MSW(mem->cookies->dmac_notused);
4206 mcp->mb[7] = LSW(mem->cookies->dmac_notused);
4207 mcp->mb[8] = LSW(mem->size);
4208 mcp->mb[9] = addr;
4209 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4210 mcp->in_mb = MBX_1|MBX_0;
4211 mcp->timeout = MAILBOX_TOV;
4212 rval = ql_mailbox_command(ha, mcp);
4213
4214 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
4215 DDI_DMA_SYNC_FORKERNEL);
4216
4217 if (rval != QL_SUCCESS) {
4218 EL(ha, "failed=%xh\n", rval);
4219 } else {
4220 /*EMPTY*/
4221 QL_PRINT_3(ha, "done\n");
4222 }
4223
4224 return (rval);
4225 }
4226
4227 /*
4228 * ql_iidma_rate
4229 * Issue get/set iidma rate command
4230 *
4231 * Input:
4232 * ha: adapter state pointer.
4233 * loop_id: n-port handle to set/get iidma rate.
4234 * idma_rate: Pointer to iidma rate.
4235 * option: iidma firmware option (set or get data).
4236 * 0 --> Get iidma rate
4237 * 1 --> Set iidma rate
4238 *
4239 * Returns:
4240 * ql local function return status code.
4241 *
4242 * Context:
4243 * Kernel context.
4244 */
4245 int
4246 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
4247 uint32_t option)
4248 {
4249 int rval;
4250 mbx_cmd_t mc = {0};
4251 mbx_cmd_t *mcp = &mc;
4252
4253 QL_PRINT_3(ha, "started\n");
4254
4255 mcp->mb[0] = MBC_PORT_PARAM;
4256 mcp->mb[1] = loop_id;
4257 mcp->mb[2] = (uint16_t)option;
4258 mcp->out_mb = MBX_0|MBX_1|MBX_2;
4259 mcp->in_mb = MBX_0|MBX_1;
4260
4261 if (option & BIT_0) {
4262 mcp->mb[3] = (uint16_t)*idma_rate;
4263 mcp->out_mb |= MBX_3;
4264 } else {
4265 mcp->in_mb |= MBX_3;
4266 }
4267
4268 mcp->timeout = MAILBOX_TOV;
4269 rval = ql_mailbox_command(ha, mcp);
4270
4271 if (rval != QL_SUCCESS) {
4272 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
4273 } else {
4274 if (option == 0) {
4275 *idma_rate = mcp->mb[3];
4276 }
4277
4278 QL_PRINT_3(ha, "done\n");
4279 }
4280
4281 return (rval);
4282 }
4283
4284 /*
4285 * ql_set_xmit_parms
4286 * Set transmit parameters
4287 *
4288 * Input:
4289 * ha: adapter state pointer.
4290 *
4291 * Returns:
4292 * ql local function return status code.
4293 *
4294 * Context:
4295 * Kernel context.
4296 */
4297 int
4298 ql_set_xmit_parms(ql_adapter_state_t *ha)
4299 {
4300 int rval;
4301 mbx_cmd_t mc = {0};
4302 mbx_cmd_t *mcp = &mc;
4303
4304 QL_PRINT_3(ha, "started\n");
4305
4306 mcp->mb[0] = MBC_XMIT_PARM;
4307 mcp->mb[1] = BIT_1;
4308 mcp->out_mb = MBX_1|MBX_0;
4309 mcp->in_mb = MBX_0;
4310 mcp->timeout = MAILBOX_TOV;
4311 rval = ql_mailbox_command(ha, mcp);
4312
4313 if (rval != QL_SUCCESS) {
4314 EL(ha, "failed=%xh\n", rval);
4315 } else {
4316 /*EMPTY*/
4317 QL_PRINT_3(ha, "done\n");
4318 }
4319 return (rval);
4320 }
4321
4322 /*
4323 * ql_fw_etrace
4324 * Firmware extended tracing.
4325 *
4326 * Input:
4327 * ha: adapter state pointer.
4328 * mem: pointer to dma memory object for command.
4329 * opt: options and opcode.
4330 * mr: pointer to mailbox in/out parameters.
4331 *
4332 * Returns:
4333 * ql local function return status code.
4334 *
4335 * Context:
4336 * Kernel context.
4337 */
4338 int
4339 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt,
4340 ql_mbx_data_t *mr)
4341 {
4342 int rval = QL_SUCCESS;
4343 mbx_cmd_t mc = {0};
4344 mbx_cmd_t *mcp = &mc;
4345 uint16_t op_code;
4346 uint64_t time;
4347
4348 QL_PRINT_3(ha, "started\n");
4349
4350 /* currently no supported options */
4351 op_code = (uint16_t)(opt & ~0xFF00);
4352
4353 mcp->mb[0] = MBC_TRACE_CONTROL;
4354 mcp->mb[1] = op_code;
4355 mcp->in_mb = MBX_0;
4356 mcp->timeout = MAILBOX_TOV;
4357
4358 switch (op_code) {
4359 case FTO_INSERT_TIME_STAMP:
4360
4361 (void) drv_getparm(TIME, &time);
4362
4363 EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
4364
4365 mcp->mb[2] = LSW(LSD(time));
4366 mcp->mb[3] = MSW(LSD(time));
4367 mcp->mb[4] = LSW(MSD(time));
4368 mcp->mb[5] = MSW(MSD(time));
4395 case FTO_FCE_TRACE_DISABLE:
4396 /* also causes ISP25xx to flush its internal FCE buffer. */
4397 mcp->mb[2] = BIT_0;
4398 mcp->out_mb = MBX_0_THRU_2;
4399 break;
4400
4401 case FTO_EXT_TRACE_DISABLE:
4402 /* just sending the opcode disables it */
4403 break;
4404
4405 default:
4406 EL(ha, "invalid option: %xh\n", opt);
4407 rval = QL_PARAMETER_ERROR;
4408 break;
4409 }
4410
4411 if (rval == QL_SUCCESS) {
4412 rval = ql_mailbox_command(ha, mcp);
4413 }
4414
4415 /* Return mailbox data. */
4416 if (mr != NULL) {
4417 mr->mb[0] = mcp->mb[0];
4418 mr->mb[1] = mcp->mb[1];
4419 mr->mb[2] = mcp->mb[2];
4420 mr->mb[3] = mcp->mb[3];
4421 mr->mb[4] = mcp->mb[4];
4422 mr->mb[5] = mcp->mb[5];
4423 mr->mb[6] = mcp->mb[6];
4424 mr->mb[7] = mcp->mb[7];
4425 mr->mb[8] = mcp->mb[8];
4426 mr->mb[9] = mcp->mb[9];
4427 }
4428
4429 if (rval != QL_SUCCESS) {
4430 EL(ha, "failed=%xh\n", rval);
4431 } else {
4432 /*EMPTY*/
4433 QL_PRINT_3(ha, "done\n");
4434 }
4435
4436 return (rval);
4437 }
4438
4439 /*
4440 * ql_reset_menlo
4441 * Reset Menlo Mailbox Command.
4442 *
4443 * Input:
4444 * ha: adapter state pointer.
4445 * mr: pointer to mailbox in/out parameters.
4446 * opt: options.
4447 *
4448 * Returns:
4449 * ql local function return status code.
4450 *
4451 * Context:
4452 * Kernel context.
4453 */
4454 int
4455 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4456 {
4457 int rval;
4458 mbx_cmd_t mc = {0};
4459 mbx_cmd_t *mcp = &mc;
4460
4461 QL_PRINT_3(ha, "started\n");
4462
4463 mcp->mb[0] = MBC_RESET_MENLO;
4464 mcp->mb[1] = opt;
4465 mcp->out_mb = MBX_1|MBX_0;
4466 mcp->in_mb = MBX_1|MBX_0;
4467 mcp->timeout = MAILBOX_TOV;
4468 rval = ql_mailbox_command(ha, mcp);
4469
4470 /* Return mailbox data. */
4471 if (mr != NULL) {
4472 mr->mb[0] = mcp->mb[0];
4473 mr->mb[1] = mcp->mb[1];
4474 }
4475
4476 if (rval != QL_SUCCESS) {
4477 EL(ha, "failed=%xh\n", rval);
4478 } else {
4479 /*EMPTY*/
4480 QL_PRINT_3(ha, "done\n");
4481 }
4482
4483 return (rval);
4484 }
4485
4486 /*
4487 * ql_restart_mpi
4488 * The Restart MPI Firmware Mailbox Command will reset the MPI RISC,
4489 * reload MPI firmware from Flash, and execute the firmware.
4490 *
4491 * Input:
4492 * ha: adapter state pointer.
4493 *
4494 * Returns:
4495 * ql local function return status code.
4496 *
4497 * Context:
4498 * Kernel context.
4499 */
4500 int
4501 ql_restart_mpi(ql_adapter_state_t *ha)
4502 {
4503 int rval;
4504 mbx_cmd_t mc = {0};
4505 mbx_cmd_t *mcp = &mc;
4506
4507 QL_PRINT_3(ha, "started\n");
4508
4509 mcp->mb[0] = MBC_RESTART_MPI;
4510 mcp->out_mb = MBX_0;
4511 mcp->in_mb = MBX_1|MBX_0;
4512 mcp->timeout = MAILBOX_TOV;
4513 rval = ql_mailbox_command(ha, mcp);
4514
4515 /* Return mailbox data. */
4516 if (rval != QL_SUCCESS) {
4517 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
4518 } else {
4519 /*EMPTY*/
4520 QL_PRINT_3(ha, "done\n");
4521 }
4522
4523 return (rval);
4524 }
4525
4526 /*
4527 * ql_idc_request
4528 * Inter-Driver Communication Request.
4529 *
4530 * Input:
4531 * ha: adapter state pointer.
4532 * mr: pointer for mailbox data.
4533 *
4534 * Returns:
4535 * ql local function return status code.
4536 *
4537 * Context:
4538 * Kernel context.
4539 */
4540 int
4541 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4542 {
4543 int rval;
4544 mbx_cmd_t mc = {0};
4545 mbx_cmd_t *mcp = &mc;
4546
4547 QL_PRINT_3(ha, "started\n");
4548
4549 mcp->mb[0] = MBC_IDC_REQUEST;
4550 mcp->mb[1] = mr->mb[1];
4551 mcp->mb[2] = mr->mb[2];
4552 mcp->mb[3] = mr->mb[3];
4553 mcp->mb[4] = mr->mb[4];
4554 mcp->mb[5] = mr->mb[5];
4555 mcp->mb[6] = mr->mb[6];
4556 mcp->mb[7] = mr->mb[7];
4557 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4558 mcp->in_mb = MBX_2|MBX_0;
4559 mcp->timeout = MAILBOX_TOV;
4560 rval = ql_mailbox_command(ha, mcp);
4561
4562 if (rval == QL_SUCCESS) {
4563 mr->mb[2] = mcp->mb[2];
4564 QL_PRINT_3(ha, "done\n");
4565 } else {
4566 EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]);
4567 }
4568
4569 return (rval);
4570 }
4571
4572 /*
4573 * ql_idc_ack
4574 * Inter-Driver Communication Acknowledgement.
4575 *
4576 * Input:
4577 * ha: adapter state pointer.
4578 *
4579 * Returns:
4580 * ql local function return status code.
4581 *
4582 * Context:
4583 * Kernel context.
4584 */
4585 int
4586 ql_idc_ack(ql_adapter_state_t *ha)
4587 {
4588 int rval;
4589 mbx_cmd_t mc = {0};
4590 mbx_cmd_t *mcp = &mc;
4591
4592 QL_PRINT_3(ha, "started\n");
4593
4594 mcp->mb[0] = MBC_IDC_ACK;
4595 mcp->mb[1] = ha->idc_mb[1];
4596 mcp->mb[2] = ha->idc_mb[2];
4597 mcp->mb[3] = ha->idc_mb[3];
4598 mcp->mb[4] = ha->idc_mb[4];
4599 mcp->mb[5] = ha->idc_mb[5];
4600 mcp->mb[6] = ha->idc_mb[6];
4601 mcp->mb[7] = ha->idc_mb[7];
4602 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4603 mcp->in_mb = MBX_0;
4604 mcp->timeout = MAILBOX_TOV;
4605 rval = ql_mailbox_command(ha, mcp);
4606
4607 QL_PRINT_3(ha, "done\n");
4608
4609 return (rval);
4610 }
4611
4612 /*
4613 * ql_idc_time_extend
4614 * Inter-Driver Communication Time Extend
4615 *
4616 * Input:
4617 * ha: adapter state pointer.
4618 *
4619 * Returns:
4620 * ql local function return status code.
4621 *
4622 * Context:
4623 * Kernel context.
4624 */
4625 int
4626 ql_idc_time_extend(ql_adapter_state_t *ha)
4627 {
4628 int rval;
4629 mbx_cmd_t mc = {0};
4630 mbx_cmd_t *mcp = &mc;
4631
4632 QL_PRINT_3(ha, "started\n");
4633
4634 mcp->mb[0] = MBC_IDC_TIME_EXTEND;
4635 mcp->mb[1] = ha->idc_mb[1];
4636 mcp->mb[2] = ha->idc_mb[2];
4637 mcp->mb[3] = ha->idc_mb[3];
4638 mcp->mb[4] = ha->idc_mb[4];
4639 mcp->mb[5] = ha->idc_mb[5];
4640 mcp->mb[6] = ha->idc_mb[6];
4641 mcp->mb[7] = ha->idc_mb[7];
4642 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4643 mcp->in_mb = MBX_0;
4644 mcp->timeout = MAILBOX_TOV;
4645 rval = ql_mailbox_command(ha, mcp);
4646
4647 QL_PRINT_3(ha, "done\n");
4648
4649 return (rval);
4650 }
4651
4652 /*
4653 * ql_port_reset
4654 * The Port Reset for the external 10G port associated with this function.
4655 *
4656 * Input:
4657 * ha: adapter state pointer.
4658 *
4659 * Returns:
4660 * ql local function return status code.
4661 *
4662 * Context:
4663 * Kernel context.
4664 */
4665 int
4666 ql_port_reset(ql_adapter_state_t *ha)
4667 {
4668 int rval;
4669 mbx_cmd_t mc = {0};
4670 mbx_cmd_t *mcp = &mc;
4671
4672 QL_PRINT_3(ha, "started\n");
4673
4674 mcp->mb[0] = MBC_PORT_RESET;
4675 mcp->out_mb = MBX_0;
4676 mcp->in_mb = MBX_0;
4677 mcp->timeout = MAILBOX_TOV;
4678 rval = ql_mailbox_command(ha, mcp);
4679
4680 QL_PRINT_3(ha, "done\n");
4681
4682 return (rval);
4683 }
4684
4685 /*
4686 * ql_set_port_config
4687 * The Set Port Configuration command sets the configuration for the
4688 * external 10G port associated with this function.
4689 *
4690 * Input:
4691 * ha: adapter state pointer.
4692 * mr: pointer for mailbox data.
4693 *
4694 * Returns:
4695 * ql local function return status code.
4696 *
4697 * Context:
4698 * Kernel context.
4699 */
4700 int
4701 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4702 {
4703 int rval;
4704 mbx_cmd_t mc = {0};
4705 mbx_cmd_t *mcp = &mc;
4706
4707 QL_PRINT_3(ha, "started\n");
4708
4709 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4710 mcp->mb[1] = mrp->mb[1];
4711 mcp->mb[2] = mrp->mb[2];
4712 mcp->mb[3] = mrp->mb[3];
4713 mcp->mb[4] = mrp->mb[4];
4714 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4715 mcp->in_mb = MBX_0;
4716 mcp->timeout = MAILBOX_TOV;
4717 rval = ql_mailbox_command(ha, mcp);
4718
4719 QL_PRINT_3(ha, "done\n");
4720
4721 return (rval);
4722 }
4723
4724 /*
4725 * ql_get_port_config
4726 * The Get Port Configuration command retrieves the current configuration
4727 * for the external 10G port associated with this function.
4728 *
4729 * Input:
4730 * ha: adapter state pointer.
4731 * mr: pointer for mailbox data.
4732 *
4733 * Returns:
4734 * ql local function return status code.
4735 *
4736 * Context:
4737 * Kernel context.
4738 */
4739 int
4740 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4741 {
4742 int rval;
4743 mbx_cmd_t mc = {0};
4744 mbx_cmd_t *mcp = &mc;
4745
4746 QL_PRINT_3(ha, "started\n");
4747
4748 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4749 mcp->out_mb = MBX_0;
4750 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4751 mcp->timeout = MAILBOX_TOV;
4752 rval = ql_mailbox_command(ha, mcp);
4753
4754 if (rval == QL_SUCCESS) {
4755 if (mrp != NULL) {
4756 mrp->mb[1] = mcp->mb[1];
4757 mrp->mb[2] = mcp->mb[2];
4758 mrp->mb[3] = mcp->mb[3];
4759 mrp->mb[4] = mcp->mb[4];
4760 }
4761 QL_PRINT_3(ha, "done\n");
4762 } else {
4763 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n",
4764 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]);
4765 }
4766
4767 return (rval);
4768 }
4769
4770 /*
4771 * ql_flash_access
4772 * The Get Port Configuration command retrieves the current configuration
4773 * for the external 10G port associated with this function
4774 *
4775 * Input:
4776 * ha: adapter state pointer.
4777 * cmd: command.
4778 * start: 32bit word address.
4779 * end: 32bit word address.
4780 * dp: 32bit word pointer.
4781 *
4782 * Returns:
4783 * ql local function return status code.
4784 *
4785 * Context:
4786 * Kernel context.
4787 */
4788 int
4789 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start,
4790 uint32_t end, uint32_t *dp)
4791 {
4792 int rval;
4793 mbx_cmd_t mc = {0};
4794 mbx_cmd_t *mcp = &mc;
4795
4796 QL_PRINT_3(ha, "started, cmd=%xh\n", cmd);
4797
4798 mcp->mb[0] = MBC_FLASH_ACCESS;
4799 mcp->mb[1] = cmd;
4800 mcp->mb[2] = LSW(start);
4801 mcp->mb[3] = MSW(start);
4802 mcp->mb[4] = LSW(end);
4803 mcp->mb[5] = MSW(end);
4804
4805 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4806 mcp->in_mb = MBX_0_THRU_4;
4807 mcp->timeout = MAILBOX_TOV;
4808 rval = ql_mailbox_command(ha, mcp);
4809
4810 if (rval != QL_SUCCESS) {
4811 EL(ha, "cmd=%xh, status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, "
4812 "mbx4=%xh\n", cmd, rval, mcp->mb[1], mcp->mb[2],
4813 mcp->mb[3], mcp->mb[4]);
4814 } else {
4815 if (dp != NULL) {
4816 *dp = (uint32_t)mcp->mb[1];
4817 }
4818 QL_PRINT_3(ha, "done\n");
4819 }
4820
4821 return (rval);
4822 }
4823
4824 /*
4825 * ql_get_xgmac_stats
4826 * Issue et XGMAC Statistics Mailbox command
4827 *
4828 * Input:
4829 * ha: adapter state pointer.
4830 * size: size of data buffer.
4831 * bufp: data pointer for DMA data.
4832 *
4833 * Returns:
4834 * ql local function return status code.
4835 *
4836 * Context:
4837 * Kernel context.
4838 */
4839 int
4840 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
4841 {
4842 int rval;
4843 dma_mem_t mem_desc;
4844 mbx_cmd_t mc = {0};
4845 mbx_cmd_t *mcp = &mc;
4846
4847 QL_PRINT_3(ha, "started\n");
4848
4849 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4850 (uint32_t)size)) != QL_SUCCESS) {
4851 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
4852 return (QL_MEMORY_ALLOC_FAILED);
4853 }
4854
4855 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4856 mcp->mb[2] = MSW(mem_desc.cookie.dmac_address);
4857 mcp->mb[3] = LSW(mem_desc.cookie.dmac_address);
4858 mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused);
4859 mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused);
4860 mcp->mb[8] = (uint16_t)(size >> 2);
4861 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4862 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4863 mcp->timeout = MAILBOX_TOV;
4864 rval = ql_mailbox_command(ha, mcp);
4865
4866 if (rval == QL_SUCCESS) {
4867 ql_get_mbox_dma_data(&mem_desc, bufp);
4868 }
4869 ql_free_dma_resource(ha, &mem_desc);
4870
4871 if (rval != QL_SUCCESS) {
4872 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4873 mcp->mb[2]);
4874 } else {
4875 /*EMPTY*/
4876 QL_PRINT_3(ha, "done\n");
4877 }
4878
4879 return (rval);
4880 }
4881
4882 /*
4883 * ql_get_dcbx_params
4884 * Issue get DCBX parameters mailbox command.
4885 *
4886 * Input:
4887 * ha: adapter state pointer.
4888 * size: size of data buffer.
4889 * bufp: data pointer for DMA data.
4890 *
4891 * Returns:
4892 * ql local function return status code.
4893 *
4894 * Context:
4895 * Kernel context.
4896 */
4897 int
4898 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp)
4899 {
4900 int rval;
4901 dma_mem_t mem_desc;
4902 mbx_cmd_t mc = {0};
4903 mbx_cmd_t *mcp = &mc;
4904
4905 QL_PRINT_3(ha, "started\n");
4906
4907 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) !=
4908 QL_SUCCESS) {
4909 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4910 return (QL_MEMORY_ALLOC_FAILED);
4911 }
4912
4913 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4914 mcp->mb[1] = 0; /* Return all DCBX paramters */
4915 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4916 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4917 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4918 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4919 mcp->mb[8] = (uint16_t)size;
4920 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4921 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4922 mcp->timeout = MAILBOX_TOV;
4923 rval = ql_mailbox_command(ha, mcp);
4924
4925 if (rval == QL_SUCCESS) {
4926 ql_get_mbox_dma_data(&mem_desc, bufp);
4927 }
4928
4929 ql_free_dma_resource(ha, &mem_desc);
4930
4931 if (rval != QL_SUCCESS) {
4932 EL(ha, "failed=%xh\n", rval);
4933 } else {
4934 /*EMPTY*/
4935 QL_PRINT_3(ha, "done\n");
4936 }
4937
4938 return (rval);
4939 }
4940 /*
4941 * ql_get_fcf_list
4942 * Issue get FCF list mailbox command.
4943 *
4944 * Input:
4945 * ha: adapter state pointer.
4946 * fcf_list: pointer to ql_fcf_list_desc_t
4947 * bufp: data pointer for DMA data.
4948 *
4949 * Returns:
4950 * ql local function return status code.
4951 *
4952 * Context:
4953 * Kernel context.
4954 */
4955
4956 int
4957 ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list,
4958 caddr_t bufp)
4959 {
4960 int rval;
4961 dma_mem_t mem_desc;
4962 mbx_cmd_t mc = {0};
4963 mbx_cmd_t *mcp = &mc;
4964
4965 QL_PRINT_3(ha, "started\n");
4966
4967 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4968 fcf_list->buffer_size)) !=
4969 QL_SUCCESS) {
4970 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4971 return (QL_MEMORY_ALLOC_FAILED);
4972 }
4973
4974 mcp->mb[0] = MBC_GET_FCF_LIST;
4975 mcp->mb[1] = fcf_list->options;
4976 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4977 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4978 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4979 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4980 mcp->mb[8] = (uint16_t)fcf_list->buffer_size;
4981 mcp->mb[9] = fcf_list->fcf_index;
4982 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4983 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4984 mcp->timeout = MAILBOX_TOV;
4985 rval = ql_mailbox_command(ha, mcp);
4986
4987 if (rval == QL_SUCCESS) {
4988 ql_get_mbox_dma_data(&mem_desc, bufp);
4989 fcf_list->buffer_size = (uint16_t)mcp->mb[1];
4990 }
4991
4992 ql_free_dma_resource(ha, &mem_desc);
4993
4994 if (rval != QL_SUCCESS) {
4995 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4996 mcp->mb[2]);
4997 } else {
4998 /*EMPTY*/
4999 QL_PRINT_3(ha, "done\n");
5000 }
5001
5002 return (rval);
5003 }
5004
5005 /*
5006 * ql_get_resource_cnts
5007 * Issue get Resourse Count mailbox command.
5008 *
5009 * Input:
5010 * ha: adapter state pointer.
5011 * mr: pointer for mailbox data.
5012 *
5013 * Returns:
5014 * ql local function return status code.
5015 *
5016 * Context:
5017 * Kernel context.
5018 */
5019
5020 int
5021 ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5022 {
5023 int rval;
5024 mbx_cmd_t mc = {0};
5025 mbx_cmd_t *mcp = &mc;
5026
5027 QL_PRINT_3(ha, "started\n");
5028
5029 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
5030 mcp->out_mb = MBX_9|MBX_1|MBX_0;
5031 mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
5032 MBX_3|MBX_2|MBX_1|MBX_0;
5033 mcp->timeout = MAILBOX_TOV;
5034 rval = ql_mailbox_command(ha, mcp);
5035
5036 /* Return mailbox data. */
5037 if (mr != NULL) {
5038 mr->mb[1] = mcp->mb[1];
5039 mr->mb[2] = mcp->mb[2];
5040 mr->mb[3] = mcp->mb[3];
5041 mr->mb[6] = mcp->mb[6];
5042 mr->mb[7] = mcp->mb[7];
5043 mr->mb[10] = mcp->mb[10];
5044 mr->mb[11] = mcp->mb[11];
5045 mr->mb[12] = mcp->mb[12];
5046 }
5047
5048 if (rval != QL_SUCCESS) {
5049 EL(ha, "failed=%xh\n", rval);
5050 } else {
5051 /*EMPTY*/
5052 QL_PRINT_3(ha, "done\n");
5053 }
5054
5055 return (rval);
5056 }
5057
5058 /*
5059 * ql_toggle_interrupt
5060 * Issue Toggle Interrupt Mailbox Command.
5061 *
5062 * Input:
5063 * ha: adapter state pointer.
5064 * opt: 0 = disable, 1 = enable.
5065 *
5066 * Returns:
5067 * ql local function return status code.
5068 *
5069 * Context:
5070 * Kernel context.
5071 */
5072 int
5073 ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt)
5074 {
5075 int rval;
5076 mbx_cmd_t mc = {0};
5077 mbx_cmd_t *mcp = &mc;
5078
5079 QL_PRINT_3(ha, "started\n");
5080
5081 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5082 mcp->mb[1] = opt;
5083 mcp->out_mb = MBX_1|MBX_0;
5084 mcp->in_mb = MBX_0;
5085 mcp->timeout = 2;
5086 rval = ql_mailbox_command(ha, mcp);
5087
5088 if (rval != QL_SUCCESS) {
5089 EL(ha, "failed=%xh\n", rval);
5090 } else {
5091 /*EMPTY*/
5092 QL_PRINT_3(ha, "done\n");
5093 }
5094
5095 return (rval);
5096 }
5097
5098 /*
5099 * ql_get_md_template
5100 * Issue request mini-dump template Mailbox command
5101 *
5102 * Input:
5103 * ha: adapter state pointer.
5104 * mem: pointer to dma memory object for command.
5105 * mr: pointer for return mailboxes.
5106 * ofst: template offset.
5107 * opt: request command code.
5108 * GTO_TEMPLATE_SIZE = Request Template Size.
5109 * GTO_TEMPLATE = Request Template.
5110 *
5111 * Returns:
5112 * ql local function return status code.
5113 *
5114 * Context:
5115 * Kernel context.
5116 */
5117 int
5118 ql_get_md_template(ql_adapter_state_t *ha, dma_mem_t *mem, ql_mbx_data_t *mr,
5119 uint32_t ofst, uint16_t opt)
5120 {
5121 int rval;
5122 mbx_cmd_t mc = {0};
5123 mbx_cmd_t *mcp = &mc;
5124
5125 QL_PRINT_3(ha, "started\n");
5126
5127 mcp->mb[0] = MBC_GET_MD_TEMPLATE;
5128 mcp->mb[2] = opt;
5129 if (mem != NULL) {
5130 mcp->mb[4] = LSW(mem->cookies->dmac_address);
5131 mcp->mb[5] = MSW(mem->cookies->dmac_address);
5132 mcp->mb[6] = LSW(mem->cookies->dmac_notused);
5133 mcp->mb[7] = MSW(mem->cookies->dmac_notused);
5134 mcp->mb[8] = LSW(mem->size);
5135 mcp->mb[9] = MSW(mem->size);
5136 }
5137 if (ofst != 0) {
5138 mcp->mb[10] = LSW(ofst);
5139 mcp->mb[11] = MSW(ofst);
5140 }
5141 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
5142 MBX_2|MBX_1|MBX_0;
5143 mcp->in_mb = MBX_15|MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5144 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5145 mcp->timeout = MAILBOX_TOV;
5146 rval = ql_mailbox_command(ha, mcp);
5147
5148 /* Return mailbox data. */
5149 if (mr != NULL) {
5150 mr->mb[0] = mcp->mb[0];
5151 mr->mb[1] = mcp->mb[1];
5152 mr->mb[2] = mcp->mb[2];
5153 mr->mb[3] = mcp->mb[3];
5154 mr->mb[4] = mcp->mb[4];
5155 mr->mb[5] = mcp->mb[5];
5156 mr->mb[6] = mcp->mb[6];
5157 mr->mb[7] = mcp->mb[7];
5158 mr->mb[8] = mcp->mb[8];
5159 mr->mb[9] = mcp->mb[9];
5160 mr->mb[10] = mcp->mb[10];
5161 mr->mb[11] = mcp->mb[11];
5162 mr->mb[12] = mcp->mb[12];
5163 mr->mb[13] = mcp->mb[13];
5164 mr->mb[12] = mcp->mb[14];
5165 mr->mb[13] = mcp->mb[15];
5166 }
5167
5168 if (rval != QL_SUCCESS) {
5169 EL(ha, "failed=%xh\n", rval);
5170 } else {
5171 /*EMPTY*/
5172 QL_PRINT_3(ha, "done\n");
5173 }
5174 return (rval);
5175 }
5176
5177 /*
5178 * ql_init_req_q
5179 * Initialize request queue.
5180 *
5181 * Input:
5182 * ha: adapter state pointer.
5183 * req_q: request queue structure pointer.
5184 * opt: Initialize Multiple Queue mailbox command options.
5185 *
5186 * Returns:
5187 * ql driver local function return status codes
5188 *
5189 * Context:
5190 * Kernel context.
5191 */
5192 static int
5193 ql_init_req_q(ql_adapter_state_t *ha, ql_request_q_t *req_q, uint16_t opt)
5194 {
5195 int rval;
5196 mbx_cmd_t mc = {0};
5197 mbx_cmd_t *mcp = &mc;
5198
5199 QL_PRINT_3(ha, "started, req_q_number=%d\n", req_q->req_q_number);
5200
5201 if (!(opt & IMO_QOS_UPDATE)) {
5202 req_q->req_ring_ptr = req_q->req_ring.bp;
5203 req_q->req_ring_index = 0;
5204 req_q->req_q_cnt = (uint16_t)(req_q->req_entry_cnt - 1);
5205 WR32_MBAR_REG(ha, req_q->mbar_req_in, 0);
5206 if (req_q->req_out_shadow_ptr) {
5207 *req_q->req_out_shadow_ptr = 0;
5208 }
5209 }
5210
5211 mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5212 mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED);
5213 mcp->mb[2] = MSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5214 mcp->mb[3] = LSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5215 mcp->mb[4] = req_q->req_q_number;
5216 mcp->mb[5] = req_q->req_entry_cnt;
5217 mcp->mb[6] = MSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5218 mcp->mb[7] = LSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5219 mcp->mb[11] = ha->vp_index;
5220 mcp->mb[12] = 0;
5221 mcp->mb[14] = 1;
5222 mcp->out_mb = MBX_0_THRU_14;
5223 mcp->in_mb = MBX_0_THRU_1;
5224 mcp->timeout = MAILBOX_TOV;
5225 rval = ql_mailbox_command(ha, mcp);
5226
5227 if (rval != QL_SUCCESS) {
5228 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5229 } else {
5230 /*EMPTY*/
5231 QL_PRINT_3(ha, "done\n");
5232 }
5233 return (rval);
5234 }
5235
5236 /*
5237 * ql_init_rsp_q
5238 * Initialize response queue.
5239 *
5240 * Input:
5241 * ha: adapter state pointer.
5242 * rsp_q: response queue structure pointer.
5243 * opt: Initialize Multiple Queue mailbox command options.
5244 *
5245 * Returns:
5246 * ql driver local function return status codes
5247 *
5248 * Context:
5249 * Kernel context.
5250 */
5251 static int
5252 ql_init_rsp_q(ql_adapter_state_t *ha, ql_response_q_t *rsp_q, uint16_t opt)
5253 {
5254 int rval;
5255 mbx_cmd_t mc = {0};
5256 mbx_cmd_t *mcp = &mc;
5257
5258 QL_PRINT_3(ha, "started, rsp_q_number=%d\n", rsp_q->rsp_q_number);
5259
5260 if (!(opt & IMO_DELETE_Q)) {
5261 rsp_q->rsp_ring_ptr = rsp_q->rsp_ring.bp;
5262 rsp_q->rsp_ring_index = 0;
5263 WR32_MBAR_REG(ha, rsp_q->mbar_rsp_out, 0);
5264 if (rsp_q->rsp_in_shadow_ptr) {
5265 *rsp_q->rsp_in_shadow_ptr = 0;
5266 }
5267 }
5268
5269 mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5270 mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED |
5271 IMO_RESPONSE_Q_SERVICE);
5272 mcp->mb[2] = MSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5273 mcp->mb[3] = LSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5274 mcp->mb[4] = rsp_q->rsp_q_number;
5275 mcp->mb[5] = rsp_q->rsp_entry_cnt;
5276 mcp->mb[6] = MSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5277 mcp->mb[7] = LSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5278 mcp->mb[14] = rsp_q->msi_x_vector;
5279 mcp->out_mb = MBX_0_THRU_14;
5280 mcp->in_mb = MBX_0_THRU_1;
5281 mcp->timeout = MAILBOX_TOV;
5282 rval = ql_mailbox_command(ha, mcp);
5283
5284 if (rval != QL_SUCCESS) {
5285 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5286 } else {
5287 /*EMPTY*/
5288 QL_PRINT_3(ha, "done\n");
5289 }
5290 return (rval);
5291 }
5292
5293 /*
5294 * ql_load_flash_image
5295 * Load Flash Firmware.
5296 *
5297 * Input:
5298 * ha: adapter state pointer.
5299 *
5300 * Returns:
5301 * ql local function return status code.
5302 *
5303 * Context:
5304 * Kernel context.
5305 */
5306 int
5307 ql_load_flash_image(ql_adapter_state_t *ha)
5308 {
5309 int rval;
5310 mbx_cmd_t mc = {0};
5311 mbx_cmd_t *mcp = &mc;
5312
5313 QL_PRINT_3(ha, "started\n");
5314
5315 mcp->mb[0] = MBC_LOAD_FLASH_IMAGE;
5316 mcp->out_mb = MBX_0;
5317 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5318 mcp->timeout = MAILBOX_TOV;
5319 rval = ql_mailbox_command(ha, mcp);
5320
5321 if (rval != QL_SUCCESS) {
5322 EL(ha, "failed, rval=%xh, mbx1=%xh, mbx2=%xh\n",
5323 rval, mcp->mb[1], mcp->mb[2]);
5324 } else {
5325 /*EMPTY*/
5326 QL_PRINT_3(ha, "done\n");
5327 }
5328 return (rval);
5329 }
5330
5331 /*
5332 * ql_set_led_config
5333 * Set LED Configuration.
5334 *
5335 * Input:
5336 * ha: adapter state pointer.
5337 * mr: pointer for mailbox data.
5338 *
5339 * Returns:
5340 * ql local function return status code.
5341 *
5342 * Context:
5343 * Kernel context.
5344 */
5345 int
5346 ql_set_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5347 {
5348 int rval;
5349 mbx_cmd_t mc = {0};
5350 mbx_cmd_t *mcp = &mc;
5351
5352 QL_PRINT_3(ha, "started\n");
5353
5354 mcp->mb[0] = MBC_SET_LED_CONFIG;
5355 mcp->mb[1] = mr->mb[1];
5356 mcp->mb[2] = mr->mb[2];
5357 mcp->mb[3] = mr->mb[3];
5358 mcp->mb[4] = mr->mb[4];
5359 mcp->mb[5] = mr->mb[5];
5360 mcp->mb[6] = mr->mb[6];
5361 mcp->out_mb = MBX_0_THRU_6;
5362 mcp->in_mb = MBX_0;
5363 mcp->timeout = MAILBOX_TOV;
5364 rval = ql_mailbox_command(ha, mcp);
5365
5366 if (rval != QL_SUCCESS) {
5367 EL(ha, "failed=%xh\n", rval);
5368 } else {
5369 /*EMPTY*/
5370 QL_PRINT_3(ha, "done\n");
5371 }
5372
5373 return (rval);
5374 }
5375 /*
5376 * ql_get_led_config
5377 * Get LED Configuration.
5378 *
5379 * Input:
5380 * ha: adapter state pointer.
5381 * mr: pointer for mailbox data.
5382 *
5383 * Returns:
5384 * ql local function return status code.
5385 *
5386 * Context:
5387 * Kernel context.
5388 */
5389 int
5390 ql_get_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5391 {
5392 int rval;
5393 mbx_cmd_t mc = {0};
5394 mbx_cmd_t *mcp = &mc;
5395
5396 QL_PRINT_3(ha, "started\n");
5397
5398 mcp->mb[0] = MBC_GET_LED_CONFIG;
5399 mcp->out_mb = MBX_0;
5400 mcp->in_mb = MBX_0_THRU_6;
5401 mcp->timeout = MAILBOX_TOV;
5402 rval = ql_mailbox_command(ha, mcp);
5403
5404 /* Return config data. */
5405 if (mr != NULL) {
5406 mr->mb[1] = mcp->mb[1];
5407 mr->mb[2] = mcp->mb[2];
5408 mr->mb[3] = mcp->mb[3];
5409 mr->mb[4] = mcp->mb[4];
5410 mr->mb[5] = mcp->mb[5];
5411 mr->mb[6] = mcp->mb[6];
5412 }
5413
5414 if (rval != QL_SUCCESS) {
5415 EL(ha, "failed=%xh\n", rval);
5416 } else {
5417 /*EMPTY*/
5418 QL_PRINT_3(ha, "done\n");
5419 }
5420
5421 return (rval);
5422 }
5423
5424 /*
5425 * ql_led_config
5426 * Set/Get Fibre Channel LED Configuration command.
5427 *
5428 * Input:
5429 * ha: adapter state pointer.
5430 * opt: Options.
5431 * led0: LED 0 configuration.
5432 * led1: LED 1 configuration.
5433 * led2: LED 2 configuration.
5434 * mr: pointer for mailbox data.
5435 *
5436 * Returns:
5437 * qlc local function return status code.
5438 *
5439 * Context:
5440 * Kernel context.
5441 */
5442 int
5443 ql_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5444 {
5445 int rval = QL_SUCCESS;
5446 mbx_cmd_t mc = {0};
5447 mbx_cmd_t *mcp = &mc;
5448
5449 QL_PRINT_3(ha, "started\n");
5450
5451 mcp->mb[0] = MBC_FC_LED_CONFIG;
5452 mcp->mb[1] = mr->mb[1];
5453 mcp->mb[2] = mr->mb[2];
5454 mcp->mb[3] = mr->mb[3];
5455 mcp->mb[4] = mr->mb[4];
5456 mcp->out_mb = MBX_0_THRU_4;
5457 mcp->in_mb = MBX_0_THRU_4;
5458 mcp->timeout = MAILBOX_TOV;
5459 rval = ql_mailbox_command(ha, mcp);
5460
5461 /* Return mailbox data. */
5462 mr->mb[0] = mcp->mb[0];
5463 mr->mb[1] = mcp->mb[1];
5464 mr->mb[2] = mcp->mb[2];
5465 mr->mb[3] = mcp->mb[3];
5466 mr->mb[4] = mcp->mb[4];
5467
5468 if (rval != QL_SUCCESS) {
5469 EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5470 } else {
5471 /*EMPTY*/
5472 QL_PRINT_3(ha, "done\n");
5473 }
5474 return (rval);
5475 }
5476
5477 /*
5478 * ql_write_remote_reg
5479 * Writes a register within another function.
5480 *
5481 * Input:
5482 * ha: adapter state pointer.
5483 * addr: address.
5484 * data: data.
5485 *
5486 * Returns:
5487 * ql local function return status code.
5488 *
5489 * Context:
5490 * Kernel context.
5491 */
5492 int
5493 ql_write_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
5494 {
5495 int rval;
5496 mbx_cmd_t mc = {0};
5497 mbx_cmd_t *mcp = &mc;
5498
5499 QL_PRINT_10(ha, "started, addr=%xh, data=%xh\n", addr, data);
5500
5501 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5502 mcp->mb[1] = LSW(addr);
5503 mcp->mb[2] = MSW(addr);
5504 mcp->mb[3] = LSW(data);
5505 mcp->mb[4] = MSW(data);
5506 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5507 mcp->in_mb = MBX_1|MBX_0;
5508 mcp->timeout = MAILBOX_TOV;
5509 rval = ql_mailbox_command(ha, mcp);
5510
5511 if (rval != QL_SUCCESS) {
5512 EL(ha, "failed=%xh, mbx1=%xh, addr=%xh, data=%xh\n", rval,
5513 mcp->mb[1], addr, data);
5514 } else {
5515 /*EMPTY*/
5516 QL_PRINT_10(ha, "done\n");
5517 }
5518 return (rval);
5519 }
5520
5521 /*
5522 * ql_read_remote_reg
5523 * Read a register within another function.
5524 *
5525 * Input:
5526 * ha: adapter state pointer.
5527 * addr: address.
5528 * data: data pointer.
5529 *
5530 * Returns:
5531 * qlc local function return status code.
5532 *
5533 * Context:
5534 * Kernel context.
5535 */
5536 int
5537 ql_read_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t *dp)
5538 {
5539 int rval;
5540 mbx_cmd_t mc = {0};
5541 mbx_cmd_t *mcp = &mc;
5542
5543 QL_PRINT_10(ha, "started, addr=%xh\n", addr);
5544
5545 mcp->mb[0] = MBC_READ_REMOTE_REG;
5546 mcp->mb[1] = LSW(addr);
5547 mcp->mb[2] = MSW(addr);
5548 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5549 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5550 mcp->timeout = MAILBOX_TOV;
5551 rval = ql_mailbox_command(ha, mcp);
5552
5553 if (rval != QL_SUCCESS) {
5554 EL(ha, "failed=%xh, mbx1=%xh, addr=%xh\n", rval, mcp->mb[1],
5555 addr);
5556 } else {
5557 *dp = SHORT_TO_LONG(mcp->mb[3], mcp->mb[4]);
5558 QL_PRINT_10(ha, "done, addr=%xh, data=%xh\n", addr, *dp);
5559 }
5560 return (rval);
5561 }
5562
5563 /*
5564 * ql_get_temp
5565 * Issue get temperature mailbox command.
5566 *
5567 * Input:
5568 * ha: adapter state pointer.
5569 * mr: pointer for mailbox data.
5570 *
5571 * Returns:
5572 * ql local function return status code.
5573 *
5574 * Context:
5575 * Kernel context.
5576 */
5577 int
5578 ql_get_temp(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5579 {
5580 int rval;
5581 mbx_cmd_t mc = {0};
5582 mbx_cmd_t *mcp = &mc;
5583
5584 QL_PRINT_3(ha, "started\n");
5585
5586 mcp->mb[0] = MBC_GET_PARAMETERS;
5587 mcp->mb[1] = READ_ASIC_TEMP << 8;
5588 mcp->out_mb = MBX_0_THRU_1;
5589 mcp->in_mb = MBX_0_THRU_1;
5590 mcp->timeout = MAILBOX_TOV;
5591 rval = ql_mailbox_command(ha, mcp);
5592
5593 /* Return config data. */
5594 if (mr != NULL) {
5595 mr->mb[1] = mcp->mb[1];
5596 }
5597
5598 if (rval != QL_SUCCESS) {
5599 EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5600 } else {
5601 /*EMPTY*/
5602 QL_PRINT_3(ha, "done\n");
5603 }
5604 return (rval);
5605 }
5606
5607 /*
5608 * ql_write_serdes
5609 * Issue write FC serdes register mailbox command.
5610 *
5611 * Input:
5612 * ha: adapter state pointer.
5613 * mr: pointer for mailbox data.
5614 *
5615 * Returns:
5616 * ql local function return status code.
5617 *
5618 * Context:
5619 * Kernel context.
5620 */
5621 int
5622 ql_write_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5623 {
5624 int rval;
5625 mbx_cmd_t mc = {0};
5626 mbx_cmd_t *mcp = &mc;
5627
5628 QL_PRINT_3(ha, "started\n");
5629
5630 mcp->mb[0] = MBC_WRITE_SERDES_REG;
5631 mcp->mb[1] = mr->mb[1];
5632 mcp->mb[2] = mr->mb[2];
5633 mcp->mb[3] = mr->mb[3];
5634 mcp->mb[4] = mr->mb[4];
5635 mcp->mb[5] = mr->mb[5];
5636 mcp->mb[6] = mr->mb[6];
5637 mcp->out_mb = MBX_0_THRU_6;
5638 mcp->in_mb = MBX_0;
5639 mcp->timeout = MAILBOX_TOV;
5640 rval = ql_mailbox_command(ha, mcp);
5641
5642 if (rval != QL_SUCCESS) {
5643 EL(ha, "failed, rval=%xh\n", rval);
5644 } else {
5645 /*EMPTY*/
5646 QL_PRINT_3(ha, "done\n");
5647 }
5648
5649 return (rval);
5650 }
5651
5652 /*
5653 * ql_read_serdes
5654 * Issue read FC serdes register mailbox command.
5655 *
5656 * Input:
5657 * ha: adapter state pointer.
5658 * mr: pointer for mailbox data.
5659 *
5660 * Returns:
5661 * ql local function return status code.
5662 *
5663 * Context:
5664 * Kernel context.
5665 */
5666 int
5667 ql_read_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5668 {
5669 int rval;
5670 mbx_cmd_t mc = {0};
5671 mbx_cmd_t *mcp = &mc;
5672
5673 QL_PRINT_3(ha, "started\n");
5674
5675 mcp->mb[0] = MBC_READ_SERDES_REG;
5676 mcp->mb[1] = mr->mb[1];
5677 mcp->mb[2] = mr->mb[2];
5678 mcp->mb[3] = mr->mb[3];
5679 mcp->mb[4] = mr->mb[4];
5680 mcp->mb[5] = mr->mb[5];
5681 mcp->mb[6] = mr->mb[6];
5682 mcp->out_mb = MBX_0_THRU_6;
5683 mcp->in_mb = MBX_0_THRU_6;
5684 mcp->timeout = MAILBOX_TOV;
5685 rval = ql_mailbox_command(ha, mcp);
5686
5687 /* Return mailbox data. */
5688 mr->mb[0] = mcp->mb[0];
5689 mr->mb[1] = mcp->mb[1];
5690 mr->mb[2] = mcp->mb[2];
5691 mr->mb[3] = mcp->mb[3];
5692 mr->mb[4] = mcp->mb[4];
5693 mr->mb[4] = mcp->mb[5];
5694 mr->mb[4] = mcp->mb[6];
5695
5696 if (rval != QL_SUCCESS) {
5697 EL(ha, "failed, rval=%xh", rval);
5698 } else {
5699 /*EMPTY*/
5700 QL_PRINT_3(ha, "done\n");
5701 }
5702
5703 return (rval);
5704 }
|