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