1 /*
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 }
136 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
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);
202 INTR_LOCK(ha);
203 ha->intr_claimed = B_TRUE;
204 INTR_UNLOCK(ha);
205 if (ha->mailbox_flags &
206 (MBX_INTERRUPT | MBX_ABORT) ||
207 ha->task_daemon_flags & ISP_ABORT_NEEDED) {
208 break;
209 }
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.
310 */
311 static int
312 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
313 caddr_t data, uint32_t size)
314 {
315 int rval = QL_SUCCESS;
316
317 if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) ==
318 QL_SUCCESS) {
319 ql_setup_mbox_dma_data(mem_desc, data);
320 } else {
321 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
322 }
323
324 return (rval);
325 }
326
327 /*
328 * ql_setup_mbox_dma_resources
329 * Prepare a dma buffer.
330 *
331 * Input:
332 * ha = adapter state pointer.
333 * mem_desc = descriptor to contain the dma resource information.
334 * data = pointer to the data.
335 * size = size of the data in bytes.
336 *
337 * Returns:
338 * ql local function return status code.
339 *
340 * Context:
341 * Kernel context.
342 */
343 static int
344 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
345 uint32_t size)
346 {
347 int rval = QL_SUCCESS;
348
349 if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA,
350 QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
351 EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n");
352 rval = QL_MEMORY_ALLOC_FAILED;
353 }
354
355 return (rval);
356 }
357
358 /*
359 * ql_setup_mbox_dma_data
360 * Move data to the dma buffer.
361 *
362 * Input:
363 * mem_desc = descriptor to contain the dma resource information.
364 * data = pointer to the data.
365 *
366 * Returns:
367 *
368 * Context:
369 * Kernel context.
370 */
371 static void
372 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
373 {
374 /* Copy out going data to DMA buffer. */
375 ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data,
376 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
377
378 /* Sync DMA buffer. */
379 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
380 DDI_DMA_SYNC_FORDEV);
381 }
382
383 /*
384 * ql_get_mbox_dma_data
385 * Recover data from the dma buffer.
386 *
387 * Input:
388 * mem_desc = descriptor to contain the dma resource information.
389 * data = pointer to the data.
390 *
391 * Returns:
392 *
393 * Context:
394 * Kernel context.
395 */
396 static void
397 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
398 {
399 /* Sync in coming DMA buffer. */
400 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
401 DDI_DMA_SYNC_FORKERNEL);
402 /* Copy in coming DMA data. */
403 ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data,
404 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
405 }
406
407 /*
408 * ql_initialize_ip
409 * Initialize IP receive buffer queue.
410 *
411 * Input:
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));
670 mcp->mb[18] = LSW(lb->iteration_count);
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);
741
742 /* Receive data dest add in system memory bits 63-48 */
743 mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
744
745 /* Transmit data source address in system memory bits 47-32 */
746 mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
747
748 /* Transmit data source address in system memory bits 63-48 */
749 mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
750 }
751
752 /* transfer count bits 15-0 */
753 mcp->mb[10] = LSW(echo_pt->transfer_count);
754
755 /* Transmit data source address in system memory bits 15-0 */
756 mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
757
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);
999 }
1000
1001 if (rval != QL_SUCCESS) {
1002 break;
1003 }
1004 }
1005
1006 if (link != NULL) {
1007 break;
1008 }
1009 }
1010 tq = NULL;
1011 } else {
1012
1013 if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1014 rval = ql_task_mgmt_iocb(ha, tq, 0,
1015 CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
1016 } else {
1017 rval = ql_task_mgmt_iocb(ha, tq, 0,
1018 CF_TARGET_RESET, delay);
1019 }
1020 }
1021 } else {
1022 /* queue = NULL, all targets. */
1023 if (tq == NULL) {
1024 mcp->mb[0] = MBC_RESET;
1025 mcp->mb[1] = delay;
1026 mcp->out_mb = MBX_1|MBX_0;
1027 } else {
1028 mcp->mb[0] = MBC_TARGET_RESET;
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",
1767 pkt->log.entry_status, tq->d_id.b24);
1768 rval = QL_FUNCTION_PARAMETER_ERROR;
1769 }
1770
1771 if (rval == QL_SUCCESS) {
1772 if (pkt->log.rsp_size == 0xB) {
1773 LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1774 tq->cmn_features = MSW(pkt->log.io_param[5]);
1775 LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1776 tq->conc_sequences = MSW(pkt->log.io_param[6]);
1777 tq->relative_offset = LSW(pkt->log.io_param[6]);
1778 LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1779 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1780 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1781 LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1782 tq->class3_open_sequences_per_exch =
1783 MSW(pkt->log.io_param[10]);
1784 tq->prli_payload_length = 0x14;
1785 }
1786 if (mr != NULL) {
1787 LITTLE_ENDIAN_16(&pkt->log.status);
1788 LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1789 LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1790
1791 if (pkt->log.status != CS_COMPLETE) {
1792 EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1793 "%xh\n", pkt->log.status,
1794 pkt->log.io_param[0],
1795 pkt->log.io_param[1]);
1796
1797 switch (pkt->log.io_param[0]) {
1798 case CS0_NO_LINK:
1799 case CS0_FIRMWARE_NOT_READY:
1800 mr->mb[0] = MBS_COMMAND_ERROR;
1801 mr->mb[1] = 1;
1802 break;
1803 case CS0_NO_IOCB:
1804 case CS0_NO_PCB_ALLOCATED:
1805 mr->mb[0] = MBS_COMMAND_ERROR;
1806 mr->mb[1] = 2;
1807 break;
1808 case CS0_NO_EXCH_CTRL_BLK:
1809 mr->mb[0] = MBS_COMMAND_ERROR;
1810 mr->mb[1] = 3;
1811 break;
1812 case CS0_COMMAND_FAILED:
1813 mr->mb[0] = MBS_COMMAND_ERROR;
1814 mr->mb[1] = 4;
1815 switch (LSB(pkt->log.io_param[1])) {
1816 case CS1_PLOGI_RESPONSE_FAILED:
1817 mr->mb[2] = 3;
1818 break;
1819 case CS1_PRLI_FAILED:
1820 mr->mb[2] = 4;
1821 break;
1822 case CS1_PRLI_RESPONSE_FAILED:
1823 mr->mb[2] = 5;
1824 break;
1825 case CS1_COMMAND_LOGGED_OUT:
1826 mr->mb[2] = 7;
1827 break;
1828 case CS1_PLOGI_FAILED:
1829 default:
1830 EL(ha, "log iop1 = %xh\n",
1831 LSB(pkt->log.io_param[1]))
1832 mr->mb[2] = 2;
1833 break;
1834 }
1835 break;
1836 case CS0_PORT_NOT_LOGGED_IN:
1837 mr->mb[0] = MBS_COMMAND_ERROR;
1838 mr->mb[1] = 4;
1839 mr->mb[2] = 7;
1840 break;
1841 case CS0_NO_FLOGI_ACC:
1842 case CS0_NO_FABRIC_PRESENT:
1843 mr->mb[0] = MBS_COMMAND_ERROR;
1844 mr->mb[1] = 5;
1845 break;
1846 case CS0_ELS_REJECT_RECEIVED:
1847 mr->mb[0] = MBS_COMMAND_ERROR;
1848 mr->mb[1] = 0xd;
1849 break;
1850 case CS0_PORT_ID_USED:
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 =
1997 pd24->PRLI_service_parameter_word_3;
1998 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1999 }
2000 } else {
2001 tq->master_state = pd23->master_state;
2002 tq->slave_state = pd23->slave_state;
2003 if (PD_PORT_LOGIN(tq)) {
2004 /* Names are big endian. */
2005 bcopy((void *)&pd23->port_name[0],
2006 (void *)&tq->port_name[0], 8);
2007 bcopy((void *)&pd23->node_name[0],
2008 (void *)&tq->node_name[0], 8);
2009 tq->hard_addr.b.al_pa = pd23->hard_address[2];
2010 tq->hard_addr.b.area = pd23->hard_address[1];
2011 tq->hard_addr.b.domain = pd23->hard_address[0];
2012 tq->cmn_features = pd23->common_features;
2013 LITTLE_ENDIAN_16(&tq->cmn_features);
2014 tq->conc_sequences =
2015 pd23->total_concurrent_sequences;
2016 LITTLE_ENDIAN_16(&tq->conc_sequences);
2017 tq->relative_offset =
2018 pd23->RO_by_information_category;
2019 LITTLE_ENDIAN_16(&tq->relative_offset);
2020 tq->class3_recipient_ctl = pd23->recipient;
2021 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
2022 tq->class3_rcv_data_size =
2023 pd23->receive_data_size;
2024 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
2025 tq->class3_conc_sequences =
2026 pd23->concurrent_sequences;
2027 LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
2028 tq->class3_open_sequences_per_exch =
2029 pd23->open_sequences_per_exchange;
2030 LITTLE_ENDIAN_16(
2031 &tq->class3_open_sequences_per_exch);
2032 tq->prli_payload_length =
2033 pd23->PRLI_payload_length;
2034 LITTLE_ENDIAN_16(&tq->prli_payload_length);
2035 tq->prli_svc_param_word_0 =
2036 pd23->PRLI_service_parameter_word_0;
2037 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
2038 tq->prli_svc_param_word_3 =
2039 pd23->PRLI_service_parameter_word_3;
2040 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
2041 }
2042 }
2043
2044 if (!PD_PORT_LOGIN(tq)) {
2045 EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
2046 "master=%xh, slave=%xh\n", tq->d_id.b24,
2047 tq->loop_id, tq->master_state, tq->slave_state);
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) |
2377 port_no);
2378 mcp->out_mb = 0;
2379 }
2380 }
2381 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2382 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2383 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2384 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2385 mcp->in_mb = MBX_1|MBX_0;
2386 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2387 mcp->timeout = MAILBOX_TOV;
2388
2389 rval = ql_mailbox_command(ha, mcp);
2390
2391 if (rval == QL_SUCCESS) {
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);
3882
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));
4369 mcp->out_mb = MBX_0_THRU_5;
4370 break;
4371
4372 case FTO_FCE_TRACE_ENABLE:
4373 /* Firmware Fibre Channel Event Trace Buffer */
4374 mcp->mb[2] = LSW(mem->cookies->dmac_address);
4375 mcp->mb[3] = MSW(mem->cookies->dmac_address);
4376 mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4377 mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4378 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
4379 mcp->mb[8] = (uint16_t)ha->fwfcetraceopt;
4380 mcp->mb[9] = FTO_FCEMAXTRACEBUF;
4381 mcp->mb[10] = FTO_FCEMAXTRACEBUF;
4382 mcp->out_mb = MBX_0_THRU_10;
4383 break;
4384
4385 case FTO_EXT_TRACE_ENABLE:
4386 /* Firmware Extended Trace Buffer */
4387 mcp->mb[2] = LSW(mem->cookies->dmac_address);
4388 mcp->mb[3] = MSW(mem->cookies->dmac_address);
4389 mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4390 mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4391 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
4392 mcp->out_mb = MBX_0_THRU_7;
4393 break;
4394
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 }