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