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