Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP
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)) {
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 114 timer = (mcp->timeout + 20) * drv_usectohz(1000000);
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)) {
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 169 timer = mcp->timeout * drv_usectohz(1000000);
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,
↓ open down ↓ |
1269 lines elided |
↑ open up ↑ |
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 - if (pkt == NULL) {
1281 - EL(ha, "failed, kmem_zalloc\n");
1282 - return (QL_MEMORY_ALLOC_FAILED);
1283 - }
1284 1280
1285 1281 pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1286 1282 pkt->mgmt.entry_count = 1;
1287 1283
1288 1284 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1289 1285 pkt->mgmt.delay = (uint16_t)LE_16(delay);
1290 1286 pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1291 1287 pkt->mgmt.fcp_lun[2] = LSB(lun);
1292 1288 pkt->mgmt.fcp_lun[3] = MSB(lun);
1293 1289 pkt->mgmt.control_flags = LE_32(flags);
1294 1290 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1295 1291 pkt->mgmt.target_id[1] = tq->d_id.b.area;
1296 1292 pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1297 1293 pkt->mgmt.vp_index = ha->vp_index;
1298 1294
1299 1295 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1300 1296 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1301 1297 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1302 1298 pkt->sts24.entry_status, tq->d_id.b24);
1303 1299 rval = QL_FUNCTION_PARAMETER_ERROR;
1304 1300 }
1305 1301
1306 1302 LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1307 1303
1308 1304 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1309 1305 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1310 1306 pkt->sts24.comp_status, tq->d_id.b24);
1311 1307 rval = QL_FUNCTION_FAILED;
1312 1308 }
1313 1309
1314 1310 kmem_free(pkt, pkt_size);
1315 1311
1316 1312 if (rval != QL_SUCCESS) {
1317 1313 EL(ha, "failed, rval = %xh\n", rval);
1318 1314 } else {
1319 1315 /*EMPTY*/
1320 1316 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1321 1317 }
1322 1318
1323 1319 return (rval);
1324 1320 }
1325 1321
1326 1322 /*
1327 1323 * ql_loop_port_bypass
1328 1324 * Issue loop port bypass mailbox command.
1329 1325 *
1330 1326 * Input:
1331 1327 * ha: adapter state pointer.
1332 1328 * tq: target queue pointer.
1333 1329 *
1334 1330 * Returns:
1335 1331 * ql local function return status code.
1336 1332 *
1337 1333 * Context:
1338 1334 * Kernel context.
1339 1335 */
1340 1336 int
1341 1337 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1342 1338 {
1343 1339 int rval;
1344 1340 mbx_cmd_t mc = {0};
1345 1341 mbx_cmd_t *mcp = &mc;
1346 1342
1347 1343 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1348 1344
1349 1345 mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1350 1346
1351 1347 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1352 1348 mcp->mb[1] = tq->d_id.b.al_pa;
1353 1349 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1354 1350 mcp->mb[1] = tq->loop_id;
1355 1351 } else {
1356 1352 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1357 1353 }
1358 1354
1359 1355 mcp->out_mb = MBX_1|MBX_0;
1360 1356 mcp->in_mb = MBX_0;
1361 1357 mcp->timeout = MAILBOX_TOV;
1362 1358 rval = ql_mailbox_command(ha, mcp);
1363 1359
1364 1360 if (rval != QL_SUCCESS) {
1365 1361 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1366 1362 } else {
1367 1363 /*EMPTY*/
1368 1364 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1369 1365 }
1370 1366
1371 1367 return (rval);
1372 1368 }
1373 1369
1374 1370 /*
1375 1371 * ql_loop_port_enable
1376 1372 * Issue loop port enable mailbox command.
1377 1373 *
1378 1374 * Input:
1379 1375 * ha: adapter state pointer.
1380 1376 * tq: target queue pointer.
1381 1377 *
1382 1378 * Returns:
1383 1379 * ql local function return status code.
1384 1380 *
1385 1381 * Context:
1386 1382 * Kernel context.
1387 1383 */
1388 1384 int
1389 1385 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1390 1386 {
1391 1387 int rval;
1392 1388 mbx_cmd_t mc = {0};
1393 1389 mbx_cmd_t *mcp = &mc;
1394 1390
1395 1391 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1396 1392
1397 1393 mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1398 1394
1399 1395 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1400 1396 mcp->mb[1] = tq->d_id.b.al_pa;
1401 1397 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1402 1398 mcp->mb[1] = tq->loop_id;
1403 1399 } else {
1404 1400 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1405 1401 }
1406 1402 mcp->out_mb = MBX_1|MBX_0;
1407 1403 mcp->in_mb = MBX_0;
1408 1404 mcp->timeout = MAILBOX_TOV;
1409 1405 rval = ql_mailbox_command(ha, mcp);
1410 1406
1411 1407 if (rval != QL_SUCCESS) {
1412 1408 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1413 1409 } else {
1414 1410 /*EMPTY*/
1415 1411 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1416 1412 }
1417 1413
1418 1414 return (rval);
1419 1415 }
1420 1416
1421 1417 /*
1422 1418 * ql_login_lport
1423 1419 * Issue login loop port mailbox command.
1424 1420 *
1425 1421 * Input:
1426 1422 * ha: adapter state pointer.
1427 1423 * tq: target queue pointer.
1428 1424 * loop_id: FC loop id.
1429 1425 * opt: options.
1430 1426 * LLF_NONE, LLF_PLOGI
1431 1427 *
1432 1428 * Returns:
1433 1429 * ql local function return status code.
1434 1430 *
1435 1431 * Context:
1436 1432 * Kernel context.
1437 1433 */
1438 1434 int
1439 1435 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1440 1436 uint16_t opt)
1441 1437 {
1442 1438 int rval;
1443 1439 uint16_t flags;
1444 1440 ql_mbx_data_t mr;
1445 1441 mbx_cmd_t mc = {0};
1446 1442 mbx_cmd_t *mcp = &mc;
1447 1443
1448 1444 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1449 1445 ha->instance, tq->d_id.b24, loop_id);
1450 1446
1451 1447 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1452 1448 flags = CF_CMD_PLOGI;
1453 1449 if ((opt & LLF_PLOGI) == 0) {
1454 1450 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1455 1451 }
1456 1452 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1457 1453 } else {
1458 1454 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1459 1455 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1460 1456 mcp->mb[1] = loop_id;
1461 1457 } else {
1462 1458 mcp->mb[1] = (uint16_t)(loop_id << 8);
1463 1459 }
1464 1460 mcp->mb[2] = opt;
1465 1461 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1466 1462 mcp->in_mb = MBX_0;
1467 1463 mcp->timeout = MAILBOX_TOV;
1468 1464 rval = ql_mailbox_command(ha, mcp);
1469 1465 }
1470 1466
1471 1467 if (rval != QL_SUCCESS) {
1472 1468 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1473 1469 loop_id, rval);
1474 1470 } else {
1475 1471 /*EMPTY*/
1476 1472 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1477 1473 }
1478 1474
1479 1475 return (rval);
1480 1476 }
1481 1477
1482 1478 /*
1483 1479 * ql_login_fport
1484 1480 * Issue login fabric port mailbox command.
1485 1481 *
1486 1482 * Input:
1487 1483 * ha: adapter state pointer.
1488 1484 * tq: target queue pointer.
1489 1485 * loop_id: FC loop id.
1490 1486 * opt: options.
1491 1487 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1492 1488 * mr: pointer for mailbox data.
1493 1489 *
1494 1490 * Returns:
1495 1491 * ql local function return status code.
1496 1492 *
1497 1493 * Context:
1498 1494 * Kernel context.
1499 1495 */
1500 1496 int
1501 1497 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1502 1498 uint16_t opt, ql_mbx_data_t *mr)
1503 1499 {
1504 1500 int rval;
1505 1501 uint16_t flags;
1506 1502 mbx_cmd_t mc = {0};
1507 1503 mbx_cmd_t *mcp = &mc;
1508 1504
1509 1505 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1510 1506 ha->instance, tq->d_id.b24, loop_id);
1511 1507
1512 1508 if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1513 1509 opt = (uint16_t)(opt | LFF_NO_PRLI);
1514 1510 }
1515 1511
1516 1512 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1517 1513 flags = CF_CMD_PLOGI;
1518 1514 if (opt & LFF_NO_PLOGI) {
1519 1515 flags = (uint16_t)(flags | CFO_COND_PLOGI);
1520 1516 }
1521 1517 if (opt & LFF_NO_PRLI) {
1522 1518 flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1523 1519 }
1524 1520 rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1525 1521 } else {
1526 1522 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1527 1523 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1528 1524 mcp->mb[1] = loop_id;
1529 1525 mcp->mb[10] = opt;
1530 1526 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1531 1527 } else {
1532 1528 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1533 1529 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1534 1530 }
1535 1531 mcp->mb[2] = MSW(tq->d_id.b24);
1536 1532 mcp->mb[3] = LSW(tq->d_id.b24);
1537 1533 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1538 1534 mcp->timeout = MAILBOX_TOV;
1539 1535 rval = ql_mailbox_command(ha, mcp);
1540 1536
1541 1537 /* Return mailbox data. */
1542 1538 if (mr != NULL) {
1543 1539 mr->mb[0] = mcp->mb[0];
1544 1540 mr->mb[1] = mcp->mb[1];
1545 1541 mr->mb[2] = mcp->mb[2];
1546 1542 mr->mb[6] = mcp->mb[6];
1547 1543 mr->mb[7] = mcp->mb[7];
1548 1544 }
1549 1545 }
1550 1546
1551 1547 if (rval != QL_SUCCESS) {
1552 1548 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1553 1549 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1554 1550 mr->mb[2]);
1555 1551 } else {
1556 1552 /*EMPTY*/
1557 1553 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1558 1554 }
1559 1555
1560 1556 return (rval);
1561 1557 }
1562 1558
1563 1559 /*
1564 1560 * ql_logout_fabric_port
1565 1561 * Issue logout fabric port mailbox command.
1566 1562 *
1567 1563 * Input:
1568 1564 * ha: adapter state pointer.
1569 1565 * tq: target queue pointer.
1570 1566 *
1571 1567 * Returns:
1572 1568 * ql local function return status code.
1573 1569 *
1574 1570 * Context:
1575 1571 * Kernel context.
1576 1572 */
1577 1573 int
1578 1574 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1579 1575 {
1580 1576 int rval;
1581 1577 uint16_t flag;
1582 1578 ql_mbx_data_t mr;
1583 1579 mbx_cmd_t mc = {0};
1584 1580 mbx_cmd_t *mcp = &mc;
1585 1581
1586 1582 QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n",
1587 1583 ha->instance, tq->loop_id, tq->d_id.b24);
1588 1584
1589 1585 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1590 1586 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1591 1587 CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE :
1592 1588 CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1593 1589 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1594 1590 } else {
1595 1591 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0);
1596 1592 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1597 1593 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1598 1594 mcp->mb[1] = tq->loop_id;
1599 1595 mcp->mb[10] = flag;
1600 1596 mcp->out_mb = MBX_10|MBX_1|MBX_0;
1601 1597 } else {
1602 1598 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1603 1599 mcp->out_mb = MBX_1|MBX_0;
1604 1600 }
1605 1601 mcp->in_mb = MBX_0;
1606 1602 mcp->timeout = MAILBOX_TOV;
1607 1603 rval = ql_mailbox_command(ha, mcp);
1608 1604 }
1609 1605
1610 1606 if (rval != QL_SUCCESS) {
1611 1607 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1612 1608 tq->d_id.b24, tq->loop_id);
1613 1609 } else {
1614 1610 /*EMPTY*/
1615 1611 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1616 1612 }
1617 1613
1618 1614 return (rval);
1619 1615 }
1620 1616
1621 1617 /*
1622 1618 * ql_log_iocb
1623 1619 * Function issues login/logout IOCB.
1624 1620 *
1625 1621 * Input:
1626 1622 * ha: adapter state pointer.
1627 1623 * tq: target queue pointer.
1628 1624 * loop_id: FC Loop ID.
1629 1625 * flags: control flags.
1630 1626 * mr: pointer for mailbox data.
1631 1627 *
1632 1628 * Returns:
1633 1629 * ql local function return status code.
1634 1630 *
1635 1631 * Context:
1636 1632 * Kernel context.
1637 1633 */
1638 1634 int
1639 1635 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
↓ open down ↓ |
346 lines elided |
↑ open up ↑ |
1640 1636 uint16_t flags, ql_mbx_data_t *mr)
1641 1637 {
1642 1638 ql_mbx_iocb_t *pkt;
1643 1639 int rval;
1644 1640 uint32_t pkt_size;
1645 1641
1646 1642 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1647 1643
1648 1644 pkt_size = sizeof (ql_mbx_iocb_t);
1649 1645 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1650 - if (pkt == NULL) {
1651 - EL(ha, "failed, kmem_zalloc\n");
1652 - return (QL_MEMORY_ALLOC_FAILED);
1653 - }
1654 1646
1655 1647 pkt->log.entry_type = LOG_TYPE;
1656 1648 pkt->log.entry_count = 1;
1657 1649 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1658 1650 pkt->log.control_flags = (uint16_t)LE_16(flags);
1659 1651 pkt->log.port_id[0] = tq->d_id.b.al_pa;
1660 1652 pkt->log.port_id[1] = tq->d_id.b.area;
1661 1653 pkt->log.port_id[2] = tq->d_id.b.domain;
1662 1654 pkt->log.vp_index = ha->vp_index;
1663 1655
1664 1656 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1665 1657 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1666 1658 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1667 1659 pkt->log.entry_status, tq->d_id.b24);
1668 1660 rval = QL_FUNCTION_PARAMETER_ERROR;
1669 1661 }
1670 1662
1671 1663 if (rval == QL_SUCCESS) {
1672 1664 if (pkt->log.rsp_size == 0xB) {
1673 1665 LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1674 1666 tq->cmn_features = MSW(pkt->log.io_param[5]);
1675 1667 LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1676 1668 tq->conc_sequences = MSW(pkt->log.io_param[6]);
1677 1669 tq->relative_offset = LSW(pkt->log.io_param[6]);
1678 1670 LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1679 1671 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1680 1672 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1681 1673 LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1682 1674 tq->class3_open_sequences_per_exch =
1683 1675 MSW(pkt->log.io_param[10]);
1684 1676 tq->prli_payload_length = 0x14;
1685 1677 }
1686 1678 if (mr != NULL) {
1687 1679 LITTLE_ENDIAN_16(&pkt->log.status);
1688 1680 LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1689 1681 LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1690 1682
1691 1683 if (pkt->log.status != CS_COMPLETE) {
1692 1684 EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1693 1685 "%xh\n", pkt->log.status,
1694 1686 pkt->log.io_param[0],
1695 1687 pkt->log.io_param[1]);
1696 1688
1697 1689 switch (pkt->log.io_param[0]) {
1698 1690 case CS0_NO_LINK:
1699 1691 case CS0_FIRMWARE_NOT_READY:
1700 1692 mr->mb[0] = MBS_COMMAND_ERROR;
1701 1693 mr->mb[1] = 1;
1702 1694 break;
1703 1695 case CS0_NO_IOCB:
1704 1696 case CS0_NO_PCB_ALLOCATED:
1705 1697 mr->mb[0] = MBS_COMMAND_ERROR;
1706 1698 mr->mb[1] = 2;
1707 1699 break;
1708 1700 case CS0_NO_EXCH_CTRL_BLK:
1709 1701 mr->mb[0] = MBS_COMMAND_ERROR;
1710 1702 mr->mb[1] = 3;
1711 1703 break;
1712 1704 case CS0_COMMAND_FAILED:
1713 1705 mr->mb[0] = MBS_COMMAND_ERROR;
1714 1706 mr->mb[1] = 4;
1715 1707 switch (LSB(pkt->log.io_param[1])) {
1716 1708 case CS1_PLOGI_RESPONSE_FAILED:
1717 1709 mr->mb[2] = 3;
1718 1710 break;
1719 1711 case CS1_PRLI_FAILED:
1720 1712 mr->mb[2] = 4;
1721 1713 break;
1722 1714 case CS1_PRLI_RESPONSE_FAILED:
1723 1715 mr->mb[2] = 5;
1724 1716 break;
1725 1717 case CS1_COMMAND_LOGGED_OUT:
1726 1718 mr->mb[2] = 7;
1727 1719 break;
1728 1720 case CS1_PLOGI_FAILED:
1729 1721 default:
1730 1722 EL(ha, "log iop1 = %xh\n",
1731 1723 LSB(pkt->log.io_param[1]))
1732 1724 mr->mb[2] = 2;
1733 1725 break;
1734 1726 }
1735 1727 break;
1736 1728 case CS0_PORT_NOT_LOGGED_IN:
1737 1729 mr->mb[0] = MBS_COMMAND_ERROR;
1738 1730 mr->mb[1] = 4;
1739 1731 mr->mb[2] = 7;
1740 1732 break;
1741 1733 case CS0_NO_FLOGI_ACC:
1742 1734 case CS0_NO_FABRIC_PRESENT:
1743 1735 mr->mb[0] = MBS_COMMAND_ERROR;
1744 1736 mr->mb[1] = 5;
1745 1737 break;
1746 1738 case CS0_ELS_REJECT_RECEIVED:
1747 1739 mr->mb[0] = MBS_COMMAND_ERROR;
1748 1740 mr->mb[1] = 0xd;
1749 1741 break;
1750 1742 case CS0_PORT_ID_USED:
1751 1743 mr->mb[0] = MBS_PORT_ID_USED;
1752 1744 mr->mb[1] = LSW(pkt->log.io_param[1]);
1753 1745 break;
1754 1746 case CS0_N_PORT_HANDLE_USED:
1755 1747 mr->mb[0] = MBS_LOOP_ID_USED;
1756 1748 mr->mb[1] = MSW(pkt->log.io_param[1]);
1757 1749 mr->mb[2] = LSW(pkt->log.io_param[1]);
1758 1750 break;
1759 1751 case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1760 1752 mr->mb[0] = MBS_ALL_IDS_IN_USE;
1761 1753 break;
1762 1754 case CS0_CMD_PARAMETER_ERROR:
1763 1755 default:
1764 1756 EL(ha, "pkt->log iop[0]=%xh\n",
1765 1757 pkt->log.io_param[0]);
1766 1758 mr->mb[0] =
1767 1759 MBS_COMMAND_PARAMETER_ERROR;
1768 1760 break;
1769 1761 }
1770 1762 } else {
1771 1763 QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1772 1764 ha->instance, pkt->log.status);
1773 1765
1774 1766 mr->mb[0] = MBS_COMMAND_COMPLETE;
1775 1767 mr->mb[1] = (uint16_t)
1776 1768 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1777 1769 if (pkt->log.io_param[0] & BIT_8) {
1778 1770 mr->mb[1] = (uint16_t)
1779 1771 (mr->mb[1] | BIT_1);
1780 1772 }
1781 1773 }
1782 1774 rval = mr->mb[0];
1783 1775 }
1784 1776
1785 1777 }
1786 1778
1787 1779 kmem_free(pkt, pkt_size);
1788 1780
1789 1781 if (rval != QL_SUCCESS) {
1790 1782 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1791 1783 } else {
1792 1784 /*EMPTY*/
1793 1785 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1794 1786 }
1795 1787
1796 1788 return (rval);
1797 1789 }
1798 1790
1799 1791 /*
1800 1792 * ql_get_port_database
1801 1793 * Issue get port database mailbox command
1802 1794 * and copy context to device queue.
1803 1795 *
1804 1796 * Input:
1805 1797 * ha: adapter state pointer.
1806 1798 * tq: target queue pointer.
1807 1799 * opt: options.
1808 1800 * PDF_NONE, PDF_PLOGI, PDF_ADISC
1809 1801 * Returns:
1810 1802 * ql local function return status code.
1811 1803 *
1812 1804 * Context:
1813 1805 * Kernel context.
1814 1806 */
1815 1807 int
1816 1808 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1817 1809 {
1818 1810 int rval;
1819 1811 dma_mem_t mem_desc;
1820 1812 mbx_cmd_t mc = {0};
1821 1813 mbx_cmd_t *mcp = &mc;
1822 1814 port_database_23_t *pd23;
1823 1815
1824 1816 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1825 1817
1826 1818 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1827 1819 if (pd23 == NULL) {
1828 1820 rval = QL_MEMORY_ALLOC_FAILED;
1829 1821 EL(ha, "failed, rval = %xh\n", rval);
1830 1822 return (rval);
1831 1823 }
1832 1824
1833 1825 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1834 1826 PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1835 1827 return (QL_MEMORY_ALLOC_FAILED);
1836 1828 }
1837 1829
1838 1830 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1839 1831 mcp->mb[0] = MBC_GET_PORT_DATABASE;
1840 1832 mcp->mb[1] = tq->loop_id;
1841 1833 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1842 1834 mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1843 1835 mcp->mb[9] = ha->vp_index;
1844 1836 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1845 1837 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1846 1838 MBX_2|MBX_1|MBX_0;
1847 1839 } else {
1848 1840 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1849 1841 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1850 1842 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1851 1843 mcp->mb[1] = tq->loop_id;
1852 1844 mcp->mb[10] = opt;
1853 1845 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1854 1846 MBX_2|MBX_1|MBX_0;
1855 1847 } else {
1856 1848 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1857 1849 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1858 1850 }
1859 1851 }
1860 1852
1861 1853 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1862 1854 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1863 1855 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1864 1856 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1865 1857 mcp->in_mb = MBX_0;
1866 1858 mcp->timeout = MAILBOX_TOV;
1867 1859 rval = ql_mailbox_command(ha, mcp);
1868 1860
1869 1861 if (rval == QL_SUCCESS) {
1870 1862 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1871 1863 }
1872 1864
1873 1865 ql_free_dma_resource(ha, &mem_desc);
1874 1866
1875 1867 if (rval == QL_SUCCESS) {
1876 1868 if (CFG_IST(ha, CFG_CTRL_24258081)) {
1877 1869 port_database_24_t *pd24 = (port_database_24_t *)pd23;
1878 1870
1879 1871 tq->master_state = pd24->current_login_state;
1880 1872 tq->slave_state = pd24->last_stable_login_state;
1881 1873 if (PD_PORT_LOGIN(tq)) {
1882 1874 /* Names are big endian. */
1883 1875 bcopy((void *)&pd24->port_name[0],
1884 1876 (void *)&tq->port_name[0], 8);
1885 1877 bcopy((void *)&pd24->node_name[0],
1886 1878 (void *)&tq->node_name[0], 8);
1887 1879 tq->hard_addr.b.al_pa = pd24->hard_address[2];
1888 1880 tq->hard_addr.b.area = pd24->hard_address[1];
1889 1881 tq->hard_addr.b.domain = pd24->hard_address[0];
1890 1882 tq->class3_rcv_data_size =
1891 1883 pd24->receive_data_size;
1892 1884 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1893 1885 tq->prli_svc_param_word_0 =
1894 1886 pd24->PRLI_service_parameter_word_0;
1895 1887 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1896 1888 tq->prli_svc_param_word_3 =
1897 1889 pd24->PRLI_service_parameter_word_3;
1898 1890 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1899 1891 }
1900 1892 } else {
1901 1893 tq->master_state = pd23->master_state;
1902 1894 tq->slave_state = pd23->slave_state;
1903 1895 if (PD_PORT_LOGIN(tq)) {
1904 1896 /* Names are big endian. */
1905 1897 bcopy((void *)&pd23->port_name[0],
1906 1898 (void *)&tq->port_name[0], 8);
1907 1899 bcopy((void *)&pd23->node_name[0],
1908 1900 (void *)&tq->node_name[0], 8);
1909 1901 tq->hard_addr.b.al_pa = pd23->hard_address[2];
1910 1902 tq->hard_addr.b.area = pd23->hard_address[1];
1911 1903 tq->hard_addr.b.domain = pd23->hard_address[0];
1912 1904 tq->cmn_features = pd23->common_features;
1913 1905 LITTLE_ENDIAN_16(&tq->cmn_features);
1914 1906 tq->conc_sequences =
1915 1907 pd23->total_concurrent_sequences;
1916 1908 LITTLE_ENDIAN_16(&tq->conc_sequences);
1917 1909 tq->relative_offset =
1918 1910 pd23->RO_by_information_category;
1919 1911 LITTLE_ENDIAN_16(&tq->relative_offset);
1920 1912 tq->class3_recipient_ctl = pd23->recipient;
1921 1913 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
1922 1914 tq->class3_rcv_data_size =
1923 1915 pd23->receive_data_size;
1924 1916 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1925 1917 tq->class3_conc_sequences =
1926 1918 pd23->concurrent_sequences;
1927 1919 LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
1928 1920 tq->class3_open_sequences_per_exch =
1929 1921 pd23->open_sequences_per_exchange;
1930 1922 LITTLE_ENDIAN_16(
1931 1923 &tq->class3_open_sequences_per_exch);
1932 1924 tq->prli_payload_length =
1933 1925 pd23->PRLI_payload_length;
1934 1926 LITTLE_ENDIAN_16(&tq->prli_payload_length);
1935 1927 tq->prli_svc_param_word_0 =
1936 1928 pd23->PRLI_service_parameter_word_0;
1937 1929 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1938 1930 tq->prli_svc_param_word_3 =
1939 1931 pd23->PRLI_service_parameter_word_3;
1940 1932 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1941 1933 }
1942 1934 }
1943 1935
1944 1936 if (!PD_PORT_LOGIN(tq)) {
1945 1937 EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
1946 1938 "master=%xh, slave=%xh\n", tq->d_id.b24,
1947 1939 tq->loop_id, tq->master_state, tq->slave_state);
1948 1940 rval = QL_NOT_LOGGED_IN;
1949 1941 } else {
1950 1942 tq->flags = tq->prli_svc_param_word_3 &
1951 1943 PRLI_W3_TARGET_FUNCTION ?
1952 1944 tq->flags & ~TQF_INITIATOR_DEVICE :
1953 1945 tq->flags | TQF_INITIATOR_DEVICE;
1954 1946
1955 1947 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
1956 1948 tq->flags = tq->prli_svc_param_word_3 &
1957 1949 PRLI_W3_RETRY ?
1958 1950 tq->flags | TQF_TAPE_DEVICE :
1959 1951 tq->flags & ~TQF_TAPE_DEVICE;
1960 1952 } else {
1961 1953 tq->flags &= ~TQF_TAPE_DEVICE;
1962 1954 }
1963 1955 }
1964 1956 }
1965 1957
1966 1958 kmem_free(pd23, PORT_DATABASE_SIZE);
1967 1959
1968 1960 if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
1969 1961 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1970 1962 tq->loop_id, rval);
1971 1963 } else {
1972 1964 /*EMPTY*/
1973 1965 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1974 1966 }
1975 1967
1976 1968 return (rval);
1977 1969 }
1978 1970
1979 1971 /*
1980 1972 * ql_get_loop_position_map
1981 1973 * Issue get loop position map mailbox command.
1982 1974 *
1983 1975 * Input:
1984 1976 * ha: adapter state pointer.
1985 1977 * size: size of data buffer.
1986 1978 * bufp: data pointer for DMA data.
1987 1979 *
1988 1980 * Returns:
1989 1981 * ql local function return status code.
1990 1982 *
1991 1983 * Context:
1992 1984 * Kernel context.
1993 1985 */
1994 1986 int
1995 1987 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
1996 1988 {
1997 1989 int rval;
1998 1990 dma_mem_t mem_desc;
1999 1991 mbx_cmd_t mc = {0};
2000 1992 mbx_cmd_t *mcp = &mc;
2001 1993
2002 1994 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2003 1995
2004 1996 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2005 1997 (uint32_t)size)) != QL_SUCCESS) {
2006 1998 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2007 1999 return (QL_MEMORY_ALLOC_FAILED);
2008 2000 }
2009 2001
2010 2002 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2011 2003 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2012 2004 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2013 2005 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2014 2006 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2015 2007 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2016 2008 mcp->in_mb = MBX_1|MBX_0;
2017 2009 mcp->timeout = MAILBOX_TOV;
2018 2010 rval = ql_mailbox_command(ha, mcp);
2019 2011
2020 2012 if (rval == QL_SUCCESS) {
2021 2013 ql_get_mbox_dma_data(&mem_desc, bufp);
2022 2014 }
2023 2015
2024 2016 ql_free_dma_resource(ha, &mem_desc);
2025 2017
2026 2018 if (rval != QL_SUCCESS) {
2027 2019 EL(ha, "failed=%xh\n", rval);
2028 2020 } else {
2029 2021 /*EMPTY*/
2030 2022 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2031 2023 }
2032 2024
2033 2025 return (rval);
2034 2026 }
2035 2027
2036 2028 /*
2037 2029 * ql_set_rnid_params
2038 2030 * Issue set RNID parameters mailbox command.
2039 2031 *
2040 2032 * Input:
2041 2033 * ha: adapter state pointer.
2042 2034 * size: size of data buffer.
2043 2035 * bufp: data pointer for DMA data.
2044 2036 *
2045 2037 * Returns:
2046 2038 * ql local function return status code.
2047 2039 *
2048 2040 * Context:
2049 2041 * Kernel context.
2050 2042 */
2051 2043 int
2052 2044 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2053 2045 {
2054 2046 int rval;
2055 2047 dma_mem_t mem_desc;
2056 2048 mbx_cmd_t mc = {0};
2057 2049 mbx_cmd_t *mcp = &mc;
2058 2050
2059 2051 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2060 2052
2061 2053 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2062 2054 (uint32_t)size)) != QL_SUCCESS) {
2063 2055 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2064 2056 return (rval);
2065 2057 }
2066 2058
2067 2059 mcp->mb[0] = MBC_SET_PARAMETERS;
2068 2060 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2069 2061 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2070 2062 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2071 2063 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2072 2064 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2073 2065 mcp->in_mb = MBX_0;
2074 2066 mcp->timeout = MAILBOX_TOV;
2075 2067 rval = ql_mailbox_command(ha, mcp);
2076 2068
2077 2069 ql_free_dma_resource(ha, &mem_desc);
2078 2070
2079 2071 if (rval != QL_SUCCESS) {
2080 2072 EL(ha, "failed, rval = %xh\n", rval);
2081 2073 } else {
2082 2074 /*EMPTY*/
2083 2075 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2084 2076 }
2085 2077
2086 2078 return (rval);
2087 2079 }
2088 2080
2089 2081 /*
2090 2082 * ql_send_rnid_els
2091 2083 * Issue a send node identfication data mailbox command.
2092 2084 *
2093 2085 * Input:
2094 2086 * ha: adapter state pointer.
2095 2087 * loop_id: FC loop id.
2096 2088 * opt: options.
2097 2089 * size: size of data buffer.
2098 2090 * bufp: data pointer for DMA data.
2099 2091 *
2100 2092 * Returns:
2101 2093 * ql local function return status code.
2102 2094 *
2103 2095 * Context:
2104 2096 * Kernel context.
2105 2097 */
2106 2098 int
2107 2099 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2108 2100 size_t size, caddr_t bufp)
2109 2101 {
2110 2102 int rval;
2111 2103 dma_mem_t mem_desc;
2112 2104 mbx_cmd_t mc = {0};
2113 2105 mbx_cmd_t *mcp = &mc;
2114 2106
2115 2107 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2116 2108
2117 2109 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2118 2110 (uint32_t)size)) != QL_SUCCESS) {
2119 2111 return (QL_MEMORY_ALLOC_FAILED);
2120 2112 }
2121 2113
2122 2114 mcp->mb[0] = MBC_SEND_RNID_ELS;
2123 2115 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2124 2116 mcp->mb[1] = loop_id;
2125 2117 mcp->mb[9] = ha->vp_index;
2126 2118 mcp->mb[10] = opt;
2127 2119 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2128 2120 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2129 2121 mcp->mb[1] = loop_id;
2130 2122 mcp->mb[10] = opt;
2131 2123 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2132 2124 } else {
2133 2125 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2134 2126 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2135 2127 }
2136 2128 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2137 2129 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2138 2130 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2139 2131 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2140 2132 mcp->in_mb = MBX_0;
2141 2133 mcp->timeout = MAILBOX_TOV;
2142 2134 rval = ql_mailbox_command(ha, mcp);
2143 2135
2144 2136 if (rval == QL_SUCCESS) {
2145 2137 ql_get_mbox_dma_data(&mem_desc, bufp);
2146 2138 }
2147 2139
2148 2140 ql_free_dma_resource(ha, &mem_desc);
2149 2141
2150 2142 if (rval != QL_SUCCESS) {
2151 2143 EL(ha, "failed, rval = %xh\n", rval);
2152 2144 } else {
2153 2145 /*EMPTY*/
2154 2146 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2155 2147 }
2156 2148
2157 2149 return (rval);
2158 2150 }
2159 2151
2160 2152 /*
2161 2153 * ql_get_rnid_params
2162 2154 * Issue get RNID parameters mailbox command.
2163 2155 *
2164 2156 * Input:
2165 2157 * ha: adapter state pointer.
2166 2158 * size: size of data buffer.
2167 2159 * bufp: data pointer for DMA data.
2168 2160 *
2169 2161 * Returns:
2170 2162 * ql local function return status code.
2171 2163 *
2172 2164 * Context:
2173 2165 * Kernel context.
2174 2166 */
2175 2167 int
2176 2168 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2177 2169 {
2178 2170 int rval;
2179 2171 dma_mem_t mem_desc;
2180 2172 mbx_cmd_t mc = {0};
2181 2173 mbx_cmd_t *mcp = &mc;
2182 2174
2183 2175 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2184 2176
2185 2177 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2186 2178 (uint32_t)size)) != QL_SUCCESS) {
2187 2179 return (QL_MEMORY_ALLOC_FAILED);
2188 2180 }
2189 2181
2190 2182 mcp->mb[0] = MBC_GET_PARAMETERS;
2191 2183 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2192 2184 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2193 2185 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2194 2186 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2195 2187 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2196 2188 mcp->in_mb = MBX_0;
2197 2189 mcp->timeout = MAILBOX_TOV;
2198 2190 rval = ql_mailbox_command(ha, mcp);
2199 2191
2200 2192 if (rval == QL_SUCCESS) {
2201 2193 ql_get_mbox_dma_data(&mem_desc, bufp);
2202 2194 }
2203 2195
2204 2196 ql_free_dma_resource(ha, &mem_desc);
2205 2197
2206 2198 if (rval != QL_SUCCESS) {
2207 2199 EL(ha, "failed=%xh\n", rval);
2208 2200 } else {
2209 2201 /*EMPTY*/
2210 2202 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2211 2203 }
2212 2204
2213 2205 return (rval);
2214 2206 }
2215 2207
2216 2208 /*
2217 2209 * ql_get_link_status
2218 2210 * Issue get link status mailbox command.
2219 2211 *
2220 2212 * Input:
2221 2213 * ha: adapter state pointer.
2222 2214 * loop_id: FC loop id or n_port_hdl.
2223 2215 * size: size of data buffer.
2224 2216 * bufp: data pointer for DMA data.
2225 2217 * port_no: port number to query.
2226 2218 *
2227 2219 * Returns:
2228 2220 * ql local function return status code.
2229 2221 *
2230 2222 * Context:
2231 2223 * Kernel context.
2232 2224 */
2233 2225 int
2234 2226 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2235 2227 caddr_t bufp, uint8_t port_no)
2236 2228 {
2237 2229 dma_mem_t mem_desc;
2238 2230 mbx_cmd_t mc = {0};
2239 2231 mbx_cmd_t *mcp = &mc;
2240 2232 int rval = QL_SUCCESS;
2241 2233 int retry = 0;
2242 2234
2243 2235 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2244 2236
2245 2237 do {
2246 2238 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2247 2239 (uint32_t)size)) != QL_SUCCESS) {
2248 2240 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2249 2241 return (QL_MEMORY_ALLOC_FAILED);
2250 2242 }
2251 2243
2252 2244 mcp->mb[0] = MBC_GET_LINK_STATUS;
2253 2245 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2254 2246 if (loop_id == ha->loop_id) {
2255 2247 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2256 2248 mcp->mb[8] = (uint16_t)(size >> 2);
2257 2249 mcp->out_mb = MBX_10|MBX_8;
2258 2250 } else {
2259 2251 mcp->mb[1] = loop_id;
2260 2252 mcp->mb[4] = port_no;
2261 2253 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2262 2254 mcp->out_mb = MBX_10|MBX_4;
2263 2255 }
2264 2256 } else {
2265 2257 if (retry) {
2266 2258 port_no = (uint8_t)(port_no | BIT_3);
2267 2259 }
2268 2260 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2269 2261 mcp->mb[1] = loop_id;
2270 2262 mcp->mb[10] = port_no;
2271 2263 mcp->out_mb = MBX_10;
2272 2264 } else {
2273 2265 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2274 2266 port_no);
2275 2267 mcp->out_mb = 0;
2276 2268 }
2277 2269 }
2278 2270 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2279 2271 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2280 2272 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2281 2273 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2282 2274 mcp->in_mb = MBX_1|MBX_0;
2283 2275 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2284 2276 mcp->timeout = MAILBOX_TOV;
2285 2277
2286 2278 rval = ql_mailbox_command(ha, mcp);
2287 2279
2288 2280 if (rval == QL_SUCCESS) {
2289 2281 ql_get_mbox_dma_data(&mem_desc, bufp);
2290 2282 }
2291 2283
2292 2284 ql_free_dma_resource(ha, &mem_desc);
2293 2285
2294 2286 if (rval != QL_SUCCESS) {
2295 2287 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2296 2288 }
2297 2289
2298 2290 /*
2299 2291 * Some of the devices want d_id in the payload,
2300 2292 * strictly as per standard. Let's retry.
2301 2293 */
2302 2294
2303 2295 } while (rval == QL_COMMAND_ERROR && !retry++);
2304 2296
2305 2297 if (rval != QL_SUCCESS) {
2306 2298 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2307 2299 } else {
2308 2300 /*EMPTY*/
2309 2301 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2310 2302 }
2311 2303
2312 2304 return (rval);
2313 2305 }
2314 2306
2315 2307 /*
2316 2308 * ql_get_status_counts
2317 2309 * Issue get adapter link status counts mailbox command.
2318 2310 *
2319 2311 * Input:
2320 2312 * ha: adapter state pointer.
2321 2313 * loop_id: FC loop id or n_port_hdl.
2322 2314 * size: size of data buffer.
2323 2315 * bufp: data pointer for DMA data.
2324 2316 * port_no: port number to query.
2325 2317 *
2326 2318 * Returns:
2327 2319 * ql local function return status code.
2328 2320 *
2329 2321 * Context:
2330 2322 * Kernel context.
2331 2323 */
2332 2324 int
2333 2325 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2334 2326 caddr_t bufp, uint8_t port_no)
2335 2327 {
2336 2328 dma_mem_t mem_desc;
2337 2329 mbx_cmd_t mc = {0};
2338 2330 mbx_cmd_t *mcp = &mc;
2339 2331 int rval = QL_SUCCESS;
2340 2332
2341 2333 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2342 2334
2343 2335 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2344 2336 (uint32_t)size)) != QL_SUCCESS) {
2345 2337 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2346 2338 return (QL_MEMORY_ALLOC_FAILED);
2347 2339 }
2348 2340
2349 2341 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2350 2342 mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2351 2343 mcp->mb[8] = (uint16_t)(size / 4);
2352 2344 mcp->out_mb = MBX_10|MBX_8;
2353 2345 } else {
2354 2346 mcp->mb[0] = MBC_GET_LINK_STATUS;
2355 2347
2356 2348 /* allows reporting when link is down */
2357 2349 if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2358 2350 port_no = (uint8_t)(port_no | BIT_6);
2359 2351 }
2360 2352
2361 2353 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2362 2354 mcp->mb[1] = loop_id;
2363 2355 mcp->mb[10] = port_no;
2364 2356 mcp->out_mb = MBX_10|MBX_1;
2365 2357 } else {
2366 2358 mcp->mb[1] = (uint16_t)((loop_id << 8) |
2367 2359 port_no);
2368 2360 mcp->out_mb = MBX_1;
2369 2361 }
2370 2362 }
2371 2363 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2372 2364 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2373 2365 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2374 2366 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2375 2367 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2376 2368 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2377 2369 mcp->timeout = MAILBOX_TOV;
2378 2370 rval = ql_mailbox_command(ha, mcp);
2379 2371
2380 2372 if (rval == QL_SUCCESS) {
2381 2373 ql_get_mbox_dma_data(&mem_desc, bufp);
2382 2374 }
2383 2375
2384 2376 ql_free_dma_resource(ha, &mem_desc);
2385 2377
2386 2378 if (rval != QL_SUCCESS) {
2387 2379 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2388 2380 mcp->mb[1], mcp->mb[2]);
2389 2381 } else {
2390 2382 /*EMPTY*/
2391 2383 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2392 2384 }
2393 2385
2394 2386 return (rval);
2395 2387 }
2396 2388
2397 2389 /*
2398 2390 * ql_reset_link_status
2399 2391 * Issue Reset Link Error Status mailbox command
2400 2392 *
2401 2393 * Input:
2402 2394 * ha: adapter state pointer.
2403 2395 *
2404 2396 * Returns:
2405 2397 * ql local function return status code.
2406 2398 *
2407 2399 * Context:
2408 2400 * Kernel context.
2409 2401 */
2410 2402 int
2411 2403 ql_reset_link_status(ql_adapter_state_t *ha)
2412 2404 {
2413 2405 int rval;
2414 2406 mbx_cmd_t mc = {0};
2415 2407 mbx_cmd_t *mcp = &mc;
2416 2408
2417 2409 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2418 2410
2419 2411 mcp->mb[0] = MBC_RESET_LINK_STATUS;
2420 2412 mcp->out_mb = MBX_0;
2421 2413 mcp->in_mb = MBX_0;
2422 2414 mcp->timeout = MAILBOX_TOV;
2423 2415 rval = ql_mailbox_command(ha, mcp);
2424 2416
2425 2417 if (rval != QL_SUCCESS) {
2426 2418 EL(ha, "failed=%xh\n", rval);
2427 2419 } else {
2428 2420 /*EMPTY*/
2429 2421 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2430 2422 }
2431 2423
2432 2424 return (rval);
2433 2425 }
2434 2426
2435 2427 /*
2436 2428 * ql_loop_reset
2437 2429 * Issue loop reset.
2438 2430 *
2439 2431 * Input:
2440 2432 * ha: adapter state pointer.
2441 2433 *
2442 2434 * Returns:
2443 2435 * ql local function return status code.
2444 2436 *
2445 2437 * Context:
2446 2438 * Kernel context.
2447 2439 */
2448 2440 int
2449 2441 ql_loop_reset(ql_adapter_state_t *ha)
2450 2442 {
2451 2443 int rval;
2452 2444
2453 2445 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2454 2446
2455 2447 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2456 2448 rval = ql_lip_reset(ha, 0xff);
2457 2449 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2458 2450 rval = ql_full_login_lip(ha);
2459 2451 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2460 2452 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2461 2453 } else {
2462 2454 rval = ql_initiate_lip(ha);
2463 2455 }
2464 2456
2465 2457 if (rval != QL_SUCCESS) {
2466 2458 EL(ha, "failed, rval = %xh\n", rval);
2467 2459 } else {
2468 2460 /*EMPTY*/
2469 2461 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2470 2462 }
2471 2463
2472 2464 return (rval);
2473 2465 }
2474 2466
2475 2467 /*
2476 2468 * ql_initiate_lip
2477 2469 * Initiate LIP mailbox command.
2478 2470 *
2479 2471 * Input:
2480 2472 * ha: adapter state pointer.
2481 2473 *
2482 2474 * Returns:
2483 2475 * ql local function return status code.
2484 2476 *
2485 2477 * Context:
2486 2478 * Kernel context.
2487 2479 */
2488 2480 int
2489 2481 ql_initiate_lip(ql_adapter_state_t *ha)
2490 2482 {
2491 2483 int rval;
2492 2484 mbx_cmd_t mc = {0};
2493 2485 mbx_cmd_t *mcp = &mc;
2494 2486
2495 2487 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2496 2488
2497 2489 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2498 2490 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2499 2491 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2500 2492 BIT_1 : BIT_4);
2501 2493 mcp->mb[3] = ha->loop_reset_delay;
2502 2494 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2503 2495 } else {
2504 2496 mcp->mb[0] = MBC_INITIATE_LIP;
2505 2497 mcp->out_mb = MBX_0;
2506 2498 }
2507 2499 mcp->in_mb = MBX_0;
2508 2500 mcp->timeout = MAILBOX_TOV;
2509 2501 rval = ql_mailbox_command(ha, mcp);
2510 2502
2511 2503 if (rval != QL_SUCCESS) {
2512 2504 EL(ha, "failed, rval = %xh\n", rval);
2513 2505 } else {
2514 2506 /*EMPTY*/
2515 2507 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2516 2508 }
2517 2509
2518 2510 return (rval);
2519 2511 }
2520 2512
2521 2513 /*
2522 2514 * ql_full_login_lip
2523 2515 * Issue full login LIP mailbox command.
2524 2516 *
2525 2517 * Input:
2526 2518 * ha: adapter state pointer.
2527 2519 *
2528 2520 * Returns:
2529 2521 * ql local function return status code.
2530 2522 *
2531 2523 * Context:
2532 2524 * Kernel context.
2533 2525 */
2534 2526 int
2535 2527 ql_full_login_lip(ql_adapter_state_t *ha)
2536 2528 {
2537 2529 int rval;
2538 2530 mbx_cmd_t mc = {0};
2539 2531 mbx_cmd_t *mcp = &mc;
2540 2532
2541 2533 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2542 2534
2543 2535 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2544 2536 if (CFG_IST(ha, CFG_CTRL_2425)) {
2545 2537 mcp->mb[1] = BIT_3;
2546 2538 } else if (CFG_IST(ha, CFG_CTRL_8081)) {
2547 2539 mcp->mb[1] = BIT_1;
2548 2540 }
2549 2541 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2550 2542 mcp->in_mb = MBX_0;
2551 2543 mcp->timeout = MAILBOX_TOV;
2552 2544 rval = ql_mailbox_command(ha, mcp);
2553 2545
2554 2546 if (rval != QL_SUCCESS) {
2555 2547 EL(ha, "failed, rval = %xh\n", rval);
2556 2548 } else {
2557 2549 /*EMPTY*/
2558 2550 QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2559 2551 }
2560 2552
2561 2553 return (rval);
2562 2554 }
2563 2555
2564 2556 /*
2565 2557 * ql_lip_reset
2566 2558 * Issue lip reset to a port.
2567 2559 *
2568 2560 * Input:
2569 2561 * ha: adapter state pointer.
2570 2562 * loop_id: FC loop id.
2571 2563 *
2572 2564 * Returns:
2573 2565 * ql local function return status code.
2574 2566 *
2575 2567 * Context:
2576 2568 * Kernel context.
2577 2569 */
2578 2570 int
2579 2571 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2580 2572 {
2581 2573 int rval;
2582 2574 mbx_cmd_t mc = {0};
2583 2575 mbx_cmd_t *mcp = &mc;
2584 2576
2585 2577 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2586 2578
2587 2579 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2588 2580 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2589 2581 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2590 2582 BIT_1 : BIT_6);
2591 2583 mcp->mb[3] = ha->loop_reset_delay;
2592 2584 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2593 2585 } else {
2594 2586 mcp->mb[0] = MBC_LIP_RESET;
2595 2587 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2596 2588 mcp->mb[1] = loop_id;
2597 2589 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2598 2590 } else {
2599 2591 mcp->mb[1] = (uint16_t)(loop_id << 8);
2600 2592 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2601 2593 }
2602 2594 mcp->mb[2] = ha->loop_reset_delay;
2603 2595 }
2604 2596 mcp->in_mb = MBX_0;
2605 2597 mcp->timeout = MAILBOX_TOV;
2606 2598 rval = ql_mailbox_command(ha, mcp);
2607 2599
2608 2600 if (rval != QL_SUCCESS) {
2609 2601 EL(ha, "failed, rval = %xh\n", rval);
2610 2602 } else {
2611 2603 /*EMPTY*/
2612 2604 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2613 2605 }
2614 2606
2615 2607 return (rval);
2616 2608 }
2617 2609
2618 2610 /*
2619 2611 * ql_abort_command
2620 2612 * Abort command aborts a specified IOCB.
2621 2613 *
2622 2614 * Input:
2623 2615 * ha: adapter state pointer.
2624 2616 * sp: SRB structure pointer.
2625 2617 *
2626 2618 * Returns:
2627 2619 * ql local function return status code.
2628 2620 *
2629 2621 * Context:
2630 2622 * Kernel context.
2631 2623 */
2632 2624 int
2633 2625 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2634 2626 {
2635 2627 int rval;
2636 2628 mbx_cmd_t mc = {0};
2637 2629 mbx_cmd_t *mcp = &mc;
2638 2630 ql_tgt_t *tq = sp->lun_queue->target_queue;
2639 2631
2640 2632 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2641 2633
2642 2634 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2643 2635 rval = ql_abort_cmd_iocb(ha, sp);
2644 2636 } else {
2645 2637 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2646 2638 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2647 2639 mcp->mb[1] = tq->loop_id;
2648 2640 } else {
2649 2641 mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2650 2642 }
2651 2643 mcp->mb[2] = LSW(sp->handle);
2652 2644 mcp->mb[3] = MSW(sp->handle);
2653 2645 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2654 2646 sp->lun_queue->lun_no : 0);
2655 2647 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2656 2648 mcp->in_mb = MBX_0;
2657 2649 mcp->timeout = MAILBOX_TOV;
2658 2650 rval = ql_mailbox_command(ha, mcp);
2659 2651 }
2660 2652
2661 2653 if (rval != QL_SUCCESS) {
2662 2654 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2663 2655 tq->d_id.b24, sp->handle);
2664 2656 } else {
2665 2657 /*EMPTY*/
2666 2658 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2667 2659 }
2668 2660
2669 2661 return (rval);
2670 2662 }
2671 2663
2672 2664 /*
2673 2665 * ql_abort_cmd_iocb
2674 2666 * Function issues abort command IOCB.
2675 2667 *
2676 2668 * Input:
2677 2669 * ha: adapter state pointer.
2678 2670 * sp: SRB structure pointer.
2679 2671 *
2680 2672 * Returns:
2681 2673 * ql local function return status code.
2682 2674 *
2683 2675 * Context:
2684 2676 * Interrupt or Kernel context, no mailbox commands allowed.
2685 2677 */
2686 2678 static int
2687 2679 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
↓ open down ↓ |
1024 lines elided |
↑ open up ↑ |
2688 2680 {
2689 2681 ql_mbx_iocb_t *pkt;
2690 2682 int rval;
2691 2683 uint32_t pkt_size;
2692 2684 uint16_t comp_status;
2693 2685 ql_tgt_t *tq = sp->lun_queue->target_queue;
2694 2686
2695 2687 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2696 2688
2697 2689 pkt_size = sizeof (ql_mbx_iocb_t);
2698 - if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2699 - EL(ha, "failed, kmem_zalloc\n");
2700 - return (QL_MEMORY_ALLOC_FAILED);
2701 - }
2690 + pkt = kmem_zalloc(pkt_size, KM_SLEEP);
2702 2691
2703 2692 pkt->abo.entry_type = ABORT_CMD_TYPE;
2704 2693 pkt->abo.entry_count = 1;
2705 2694 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2706 2695 if (!CFG_IST(ha, CFG_CTRL_8021)) {
2707 2696 pkt->abo.options = AF_NO_ABTS;
2708 2697 }
2709 2698 pkt->abo.cmd_handle = LE_32(sp->handle);
2710 2699 pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2711 2700 pkt->abo.target_id[1] = tq->d_id.b.area;
2712 2701 pkt->abo.target_id[2] = tq->d_id.b.domain;
2713 2702 pkt->abo.vp_index = ha->vp_index;
2714 2703
2715 2704 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2716 2705
2717 2706 if (rval == QL_SUCCESS) {
2718 2707 if ((pkt->abo.entry_status & 0x3c) != 0) {
2719 2708 EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2720 2709 pkt->abo.entry_status, tq->d_id.b24);
2721 2710 rval = QL_FUNCTION_PARAMETER_ERROR;
2722 2711 } else {
2723 2712 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2724 2713 if (comp_status != CS_COMPLETE) {
2725 2714 EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2726 2715 comp_status, tq->d_id.b24);
2727 2716 rval = QL_FUNCTION_FAILED;
2728 2717 }
2729 2718 }
2730 2719 }
2731 2720
2732 2721 kmem_free(pkt, pkt_size);
2733 2722
2734 2723 if (rval != QL_SUCCESS) {
2735 2724 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2736 2725 } else {
2737 2726 /*EMPTY*/
2738 2727 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2739 2728 }
2740 2729
2741 2730 return (rval);
2742 2731 }
2743 2732
2744 2733 /*
2745 2734 * ql_verify_checksum
2746 2735 * Verify loaded RISC firmware.
2747 2736 *
2748 2737 * Input:
2749 2738 * ha = adapter state pointer.
2750 2739 *
2751 2740 * Returns:
2752 2741 * ql local function return status code.
2753 2742 *
2754 2743 * Context:
2755 2744 * Kernel context.
2756 2745 */
2757 2746 int
2758 2747 ql_verify_checksum(ql_adapter_state_t *ha)
2759 2748 {
2760 2749 int rval;
2761 2750 mbx_cmd_t mc = {0};
2762 2751 mbx_cmd_t *mcp = &mc;
2763 2752
2764 2753 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2765 2754
2766 2755 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2767 2756 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2768 2757 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2769 2758 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2770 2759 } else {
2771 2760 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2772 2761 }
2773 2762 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2774 2763 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2775 2764 mcp->timeout = MAILBOX_TOV;
2776 2765 rval = ql_mailbox_command(ha, mcp);
2777 2766
2778 2767 if (rval != QL_SUCCESS) {
2779 2768 EL(ha, "failed, rval = %xh\n", rval);
2780 2769 } else {
2781 2770 /*EMPTY*/
2782 2771 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2783 2772 }
2784 2773
2785 2774 return (rval);
2786 2775 }
2787 2776
2788 2777 /*
2789 2778 * ql_get_id_list
2790 2779 * Get d_id and loop ID list.
2791 2780 *
2792 2781 * Input:
2793 2782 * ha: adapter state pointer.
2794 2783 * bp: data pointer for DMA data.
2795 2784 * size: size of data buffer.
2796 2785 * mr: pointer for mailbox data.
2797 2786 *
2798 2787 * Returns:
2799 2788 * ql local function return status code.
2800 2789 *
2801 2790 * Context:
2802 2791 * Kernel context.
2803 2792 */
2804 2793 int
2805 2794 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2806 2795 ql_mbx_data_t *mr)
2807 2796 {
2808 2797 int rval;
2809 2798 dma_mem_t mem_desc;
2810 2799 mbx_cmd_t mc = {0};
2811 2800 mbx_cmd_t *mcp = &mc;
2812 2801
2813 2802 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2814 2803
2815 2804 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2816 2805 (uint32_t)size)) != QL_SUCCESS) {
2817 2806 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2818 2807 return (QL_MEMORY_ALLOC_FAILED);
2819 2808 }
2820 2809
2821 2810 mcp->mb[0] = MBC_GET_ID_LIST;
2822 2811 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2823 2812 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2824 2813 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2825 2814 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2826 2815 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2827 2816 mcp->mb[8] = (uint16_t)size;
2828 2817 mcp->mb[9] = ha->vp_index;
2829 2818 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2830 2819 } else {
2831 2820 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2832 2821 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2833 2822 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2834 2823 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2835 2824 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2836 2825 }
2837 2826 mcp->in_mb = MBX_1|MBX_0;
2838 2827 mcp->timeout = MAILBOX_TOV;
2839 2828 rval = ql_mailbox_command(ha, mcp);
2840 2829
2841 2830 if (rval == QL_SUCCESS) {
2842 2831 ql_get_mbox_dma_data(&mem_desc, bp);
2843 2832 }
2844 2833
2845 2834 ql_free_dma_resource(ha, &mem_desc);
2846 2835
2847 2836 /* Return mailbox data. */
2848 2837 if (mr != NULL) {
2849 2838 mr->mb[0] = mcp->mb[0];
2850 2839 mr->mb[1] = mcp->mb[1];
2851 2840 }
2852 2841
2853 2842 if (rval != QL_SUCCESS) {
2854 2843 EL(ha, "failed, rval = %xh\n", rval);
2855 2844 } else {
2856 2845 /*EMPTY*/
2857 2846 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2858 2847 }
2859 2848
2860 2849 return (rval);
2861 2850 }
2862 2851
2863 2852 /*
2864 2853 * ql_wrt_risc_ram
2865 2854 * Load RISC RAM.
2866 2855 *
2867 2856 * Input:
2868 2857 * ha: adapter state pointer.
2869 2858 * risc_address: risc ram word address.
2870 2859 * bp: DMA pointer.
2871 2860 * word_count: 16/32bit word count.
2872 2861 *
2873 2862 * Returns:
2874 2863 * ql local function return status code.
2875 2864 *
2876 2865 * Context:
2877 2866 * Kernel context.
2878 2867 */
2879 2868 int
2880 2869 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2881 2870 uint32_t word_count)
2882 2871 {
2883 2872 int rval;
2884 2873 mbx_cmd_t mc = {0};
2885 2874 mbx_cmd_t *mcp = &mc;
2886 2875
2887 2876 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2888 2877
2889 2878 if (CFG_IST(ha, CFG_CTRL_242581)) {
2890 2879 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2891 2880 mcp->mb[4] = MSW(word_count);
2892 2881 mcp->mb[5] = LSW(word_count);
2893 2882 mcp->mb[6] = MSW(MSD(bp));
2894 2883 mcp->mb[7] = LSW(MSD(bp));
2895 2884 mcp->mb[8] = MSW(risc_address);
2896 2885 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2897 2886 MBX_0;
2898 2887 } else {
2899 2888 mcp->mb[0] = MBC_LOAD_RAM;
2900 2889 mcp->mb[4] = LSW(word_count);
2901 2890 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2902 2891 }
2903 2892 mcp->mb[1] = LSW(risc_address);
2904 2893 mcp->mb[2] = MSW(LSD(bp));
2905 2894 mcp->mb[3] = LSW(LSD(bp));
2906 2895 mcp->in_mb = MBX_0;
2907 2896 mcp->timeout = MAILBOX_TOV;
2908 2897
2909 2898 rval = ql_mailbox_command(ha, mcp);
2910 2899
2911 2900 if (rval != QL_SUCCESS) {
2912 2901 EL(ha, "failed, rval = %xh\n", rval);
2913 2902 } else {
2914 2903 /*EMPTY*/
2915 2904 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2916 2905 }
2917 2906
2918 2907 return (rval);
2919 2908 }
2920 2909
2921 2910 /*
2922 2911 * ql_rd_risc_ram
2923 2912 * Get RISC RAM.
2924 2913 *
2925 2914 * Input:
2926 2915 * ha: adapter state pointer.
2927 2916 * risc_address: risc ram word address.
2928 2917 * bp: direct data pointer.
2929 2918 * word_count: 16/32bit word count.
2930 2919 *
2931 2920 * Returns:
2932 2921 * ql local function return status code.
2933 2922 *
2934 2923 * Context:
2935 2924 * Kernel context.
2936 2925 */
2937 2926 int
2938 2927 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2939 2928 uint32_t word_count)
2940 2929 {
2941 2930 int rval;
2942 2931 mbx_cmd_t mc = {0};
2943 2932 mbx_cmd_t *mcp = &mc;
2944 2933
2945 2934 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2946 2935
2947 2936 if (CFG_IST(ha, CFG_CTRL_242581)) {
2948 2937 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
2949 2938 mcp->mb[1] = LSW(risc_address);
2950 2939 mcp->mb[2] = MSW(LSD(bp));
2951 2940 mcp->mb[3] = LSW(LSD(bp));
2952 2941 mcp->mb[4] = MSW(word_count);
2953 2942 mcp->mb[5] = LSW(word_count);
2954 2943 mcp->mb[6] = MSW(MSD(bp));
2955 2944 mcp->mb[7] = LSW(MSD(bp));
2956 2945 mcp->mb[8] = MSW(risc_address);
2957 2946 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2958 2947 MBX_0;
2959 2948 } else {
2960 2949 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */
2961 2950 mcp->mb[1] = LSW(risc_address);
2962 2951 mcp->mb[2] = MSW(LSD(bp));
2963 2952 mcp->mb[3] = LSW(LSD(bp));
2964 2953 mcp->mb[4] = LSW(word_count);
2965 2954 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2966 2955 }
2967 2956 mcp->in_mb = MBX_0;
2968 2957 mcp->timeout = MAILBOX_TOV;
2969 2958 rval = ql_mailbox_command(ha, mcp);
2970 2959
2971 2960 if (rval != QL_SUCCESS) {
2972 2961 EL(ha, "failed, rval = %xh\n", rval);
2973 2962 } else {
2974 2963 /*EMPTY*/
2975 2964 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2976 2965 }
2977 2966
2978 2967 return (rval);
2979 2968 }
2980 2969
2981 2970 /*
2982 2971 * ql_wrt_risc_ram_word
2983 2972 * Write RISC RAM word.
2984 2973 *
2985 2974 * Input:
2986 2975 * ha: adapter state pointer.
2987 2976 * risc_address: risc ram word address.
2988 2977 * data: data.
2989 2978 *
2990 2979 * Returns:
2991 2980 * ql local function return status code.
2992 2981 *
2993 2982 * Context:
2994 2983 * Kernel context.
2995 2984 */
2996 2985 int
2997 2986 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
2998 2987 uint32_t data)
2999 2988 {
3000 2989 int rval;
3001 2990 mbx_cmd_t mc = {0};
3002 2991 mbx_cmd_t *mcp = &mc;
3003 2992
3004 2993 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3005 2994
3006 2995 mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3007 2996 mcp->mb[1] = LSW(risc_address);
3008 2997 mcp->mb[2] = LSW(data);
3009 2998 mcp->mb[3] = MSW(data);
3010 2999 mcp->mb[8] = MSW(risc_address);
3011 3000 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3012 3001 mcp->in_mb = MBX_0;
3013 3002 mcp->timeout = MAILBOX_TOV;
3014 3003
3015 3004 rval = ql_mailbox_command(ha, mcp);
3016 3005
3017 3006 if (rval != QL_SUCCESS) {
3018 3007 EL(ha, "failed, rval = %xh\n", rval);
3019 3008 } else {
3020 3009 /*EMPTY*/
3021 3010 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3022 3011 }
3023 3012
3024 3013 return (rval);
3025 3014 }
3026 3015
3027 3016 /*
3028 3017 * ql_rd_risc_ram_word
3029 3018 * Read RISC RAM word.
3030 3019 *
3031 3020 * Input:
3032 3021 * ha: adapter state pointer.
3033 3022 * risc_address: risc ram word address.
3034 3023 * data: data pointer.
3035 3024 *
3036 3025 * Returns:
3037 3026 * ql local function return status code.
3038 3027 *
3039 3028 * Context:
3040 3029 * Kernel context.
3041 3030 */
3042 3031 int
3043 3032 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3044 3033 uint32_t *data)
3045 3034 {
3046 3035 int rval;
3047 3036 mbx_cmd_t mc = {0};
3048 3037 mbx_cmd_t *mcp = &mc;
3049 3038
3050 3039 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3051 3040
3052 3041 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3053 3042 mcp->mb[1] = LSW(risc_address);
3054 3043 mcp->mb[8] = MSW(risc_address);
3055 3044 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3056 3045 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3057 3046 mcp->timeout = MAILBOX_TOV;
3058 3047
3059 3048 rval = ql_mailbox_command(ha, mcp);
3060 3049
3061 3050 if (rval != QL_SUCCESS) {
3062 3051 EL(ha, "failed, rval = %xh\n", rval);
3063 3052 } else {
3064 3053 *data = mcp->mb[2];
3065 3054 if (CFG_IST(ha, CFG_CTRL_24258081)) {
3066 3055 *data |= mcp->mb[3] << 16;
3067 3056 }
3068 3057 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3069 3058 }
3070 3059
3071 3060 return (rval);
3072 3061 }
3073 3062
3074 3063 /*
3075 3064 * ql_issue_mbx_iocb
3076 3065 * Issue IOCB using mailbox command
3077 3066 *
3078 3067 * Input:
3079 3068 * ha: adapter state pointer.
3080 3069 * bp: buffer pointer.
3081 3070 * size: buffer size.
3082 3071 *
3083 3072 * Returns:
3084 3073 * ql local function return status code.
3085 3074 *
3086 3075 * Context:
3087 3076 * Kernel context.
3088 3077 */
3089 3078 int
3090 3079 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3091 3080 {
3092 3081 int rval;
3093 3082 dma_mem_t mem_desc;
3094 3083 mbx_cmd_t mc = {0};
3095 3084 mbx_cmd_t *mcp = &mc;
3096 3085
3097 3086 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3098 3087
3099 3088 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3100 3089 QL_SUCCESS) {
3101 3090 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3102 3091 return (rval);
3103 3092 }
3104 3093
3105 3094 mcp->mb[0] = MBC_EXECUTE_IOCB;
3106 3095 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3107 3096 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3108 3097 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3109 3098 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3110 3099 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3111 3100 mcp->in_mb = MBX_1|MBX_0;
3112 3101 mcp->timeout = MAILBOX_TOV + 5;
3113 3102 rval = ql_mailbox_command(ha, mcp);
3114 3103
3115 3104 if (rval == QL_SUCCESS) {
3116 3105 ql_get_mbox_dma_data(&mem_desc, bp);
3117 3106 }
3118 3107
3119 3108 ql_free_dma_resource(ha, &mem_desc);
3120 3109
3121 3110 if (rval != QL_SUCCESS) {
3122 3111 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3123 3112 } else {
3124 3113 /*EMPTY*/
3125 3114 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3126 3115 }
3127 3116
3128 3117 return (rval);
3129 3118 }
3130 3119
3131 3120 /*
3132 3121 * ql_mbx_wrap_test
3133 3122 * Mailbox register wrap test.
3134 3123 *
3135 3124 * Input:
3136 3125 * ha: adapter state pointer.
3137 3126 * mr: pointer for in/out mailbox data.
3138 3127 *
3139 3128 * Returns:
3140 3129 * ql local function return status code.
3141 3130 *
3142 3131 * Context:
3143 3132 * Kernel context.
3144 3133 */
3145 3134 int
3146 3135 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3147 3136 {
3148 3137 int rval;
3149 3138 mbx_cmd_t mc = {0};
3150 3139 mbx_cmd_t *mcp = &mc;
3151 3140
3152 3141 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3153 3142
3154 3143 if (mr != NULL) {
3155 3144 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3156 3145 mcp->mb[1] = mr->mb[1];
3157 3146 mcp->mb[2] = mr->mb[2];
3158 3147 mcp->mb[3] = mr->mb[3];
3159 3148 mcp->mb[4] = mr->mb[4];
3160 3149 mcp->mb[5] = mr->mb[5];
3161 3150 mcp->mb[6] = mr->mb[6];
3162 3151 mcp->mb[7] = mr->mb[7];
3163 3152 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3164 3153 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3165 3154 mcp->timeout = MAILBOX_TOV;
3166 3155 rval = ql_mailbox_command(ha, mcp);
3167 3156 if (rval == QL_SUCCESS) {
3168 3157 mr->mb[1] = mcp->mb[1];
3169 3158 mr->mb[2] = mcp->mb[2];
3170 3159 mr->mb[3] = mcp->mb[3];
3171 3160 mr->mb[4] = mcp->mb[4];
3172 3161 mr->mb[5] = mcp->mb[5];
3173 3162 mr->mb[6] = mcp->mb[6];
3174 3163 mr->mb[7] = mcp->mb[7];
3175 3164 }
3176 3165 } else {
3177 3166 rval = QL_FUNCTION_PARAMETER_ERROR;
3178 3167 }
3179 3168
3180 3169 if (rval != QL_SUCCESS) {
3181 3170 EL(ha, "failed=%xh\n", rval);
3182 3171 } else {
3183 3172 /*EMPTY*/
3184 3173 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3185 3174 }
3186 3175
3187 3176 return (rval);
3188 3177 }
3189 3178
3190 3179 /*
3191 3180 * ql_execute_fw
3192 3181 * Start adapter firmware.
3193 3182 *
3194 3183 * Input:
3195 3184 * ha: adapter state pointer.
3196 3185 *
3197 3186 * Returns:
3198 3187 * ql local function return status code.
3199 3188 *
3200 3189 * Context:
3201 3190 * Kernel context.
3202 3191 */
3203 3192 int
3204 3193 ql_execute_fw(ql_adapter_state_t *ha)
3205 3194 {
3206 3195 int rval;
3207 3196 mbx_cmd_t mc = {0};
3208 3197 mbx_cmd_t *mcp = &mc;
3209 3198
3210 3199 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3211 3200
3212 3201 if (CFG_IST(ha, CFG_CTRL_8021)) {
3213 3202 return (QL_SUCCESS);
3214 3203 }
3215 3204
3216 3205 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3217 3206 if (CFG_IST(ha, CFG_CTRL_242581)) {
3218 3207 mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3219 3208 mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3220 3209 } else {
3221 3210 mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3222 3211 }
3223 3212 if (CFG_IST(ha, CFG_LR_SUPPORT)) {
3224 3213 mcp->mb[4] = BIT_0;
3225 3214 }
3226 3215 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3227 3216 mcp->in_mb = MBX_0;
3228 3217 mcp->timeout = MAILBOX_TOV;
3229 3218 rval = ql_mailbox_command(ha, mcp);
3230 3219
3231 3220 if (CFG_IST(ha, CFG_CTRL_2200)) {
3232 3221 rval = QL_SUCCESS;
3233 3222 }
3234 3223
3235 3224 if (rval != QL_SUCCESS) {
3236 3225 EL(ha, "failed=%xh\n", rval);
3237 3226 } else {
3238 3227 /*EMPTY*/
3239 3228 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3240 3229 }
3241 3230
3242 3231 return (rval);
3243 3232 }
3244 3233
3245 3234 /*
3246 3235 * ql_get_firmware_option
3247 3236 * Get Firmware Options Mailbox Command.
3248 3237 *
3249 3238 * Input:
3250 3239 * ha: adapter state pointer.
3251 3240 * mr: pointer for mailbox data.
3252 3241 *
3253 3242 * Returns:
3254 3243 * ql local function return status code.
3255 3244 *
3256 3245 * Context:
3257 3246 * Kernel context.
3258 3247 */
3259 3248 int
3260 3249 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3261 3250 {
3262 3251 int rval;
3263 3252 mbx_cmd_t mc = {0};
3264 3253 mbx_cmd_t *mcp = &mc;
3265 3254
3266 3255 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3267 3256
3268 3257 mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3269 3258 mcp->out_mb = MBX_0;
3270 3259 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3271 3260 mcp->timeout = MAILBOX_TOV;
3272 3261 rval = ql_mailbox_command(ha, mcp);
3273 3262
3274 3263 /* Return mailbox data. */
3275 3264 if (mr != NULL) {
3276 3265 mr->mb[0] = mcp->mb[0];
3277 3266 mr->mb[1] = mcp->mb[1];
3278 3267 mr->mb[2] = mcp->mb[2];
3279 3268 mr->mb[3] = mcp->mb[3];
3280 3269 }
3281 3270
3282 3271 if (rval != QL_SUCCESS) {
3283 3272 EL(ha, "failed=%xh\n", rval);
3284 3273 } else {
3285 3274 /*EMPTY*/
3286 3275 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
3287 3276 }
3288 3277
3289 3278 return (rval);
3290 3279 }
3291 3280
3292 3281 /*
3293 3282 * ql_set_firmware_option
3294 3283 * Set Firmware Options Mailbox Command.
3295 3284 *
3296 3285 * Input:
3297 3286 * ha: adapter state pointer.
3298 3287 * mr: pointer for mailbox data.
3299 3288 *
3300 3289 * Returns:
3301 3290 * ql local function return status code.
3302 3291 *
3303 3292 * Context:
3304 3293 * Kernel context.
3305 3294 */
3306 3295 int
3307 3296 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3308 3297 {
3309 3298 int rval;
3310 3299 mbx_cmd_t mc = {0};
3311 3300 mbx_cmd_t *mcp = &mc;
3312 3301
3313 3302 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3314 3303
3315 3304 if (mr != NULL) {
3316 3305 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3317 3306 mcp->mb[1] = mr->mb[1];
3318 3307 mcp->mb[2] = mr->mb[2];
3319 3308 mcp->mb[3] = mr->mb[3];
3320 3309 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3321 3310 mcp->in_mb = MBX_0;
3322 3311 mcp->timeout = MAILBOX_TOV;
3323 3312 rval = ql_mailbox_command(ha, mcp);
3324 3313 } else {
3325 3314 rval = QL_FUNCTION_PARAMETER_ERROR;
3326 3315 }
3327 3316
3328 3317 if (rval != QL_SUCCESS) {
3329 3318 EL(ha, "failed=%xh\n", rval);
3330 3319 } else {
3331 3320 /*EMPTY*/
3332 3321 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3333 3322 }
3334 3323
3335 3324 return (rval);
3336 3325 }
3337 3326
3338 3327 /*
3339 3328 * ql_init_firmware
3340 3329 * Initialize firmware mailbox command.
3341 3330 *
3342 3331 * Input:
3343 3332 * ha: adapter state pointer.
3344 3333 * ha->init_ctrl_blk = setup for transmit.
3345 3334 *
3346 3335 * Returns:
3347 3336 * ql local function return status code.
3348 3337 *
3349 3338 * Context:
3350 3339 * Kernel context.
3351 3340 */
3352 3341 int
3353 3342 ql_init_firmware(ql_adapter_state_t *ha)
3354 3343 {
3355 3344 int rval;
3356 3345 dma_mem_t mem_desc;
3357 3346 mbx_cmd_t mc = {0};
3358 3347 mbx_cmd_t *mcp = &mc;
3359 3348
3360 3349 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3361 3350
3362 3351 if (CFG_IST(ha, CFG_CTRL_8021)) {
3363 3352 WRT32_IO_REG(ha, req_out, 0);
3364 3353 WRT32_IO_REG(ha, resp_in, 0);
3365 3354 WRT32_IO_REG(ha, resp_out, 0);
3366 3355 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
3367 3356 WRT32_IO_REG(ha, req_in, 0);
3368 3357 WRT32_IO_REG(ha, resp_out, 0);
3369 3358 WRT32_IO_REG(ha, pri_req_in, 0);
3370 3359 WRT32_IO_REG(ha, atio_req_out, 0);
3371 3360 } else {
3372 3361 WRT16_IO_REG(ha, req_in, 0);
3373 3362 WRT16_IO_REG(ha, resp_out, 0);
3374 3363 }
3375 3364
3376 3365 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3377 3366 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3378 3367 QL_SUCCESS) {
3379 3368 EL(ha, "dma setup failed=%xh\n", rval);
3380 3369 return (rval);
3381 3370 }
3382 3371
3383 3372 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3384 3373 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3385 3374
3386 3375 if (CFG_IST(ha, CFG_SBUS_CARD)) {
3387 3376 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2200) ?
3388 3377 0x204c : 0x52);
3389 3378 }
3390 3379
3391 3380 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3392 3381 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3393 3382 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3394 3383 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3395 3384 if (CFG_IST(ha, CFG_CTRL_8081)) {
3396 3385 uint64_t ofst, addr;
3397 3386 ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *)
3398 3387 &ha->init_ctrl_blk.cb24;
3399 3388
3400 3389 mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW;
3401 3390 if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) {
3402 3391 ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb;
3403 3392 addr = mem_desc.cookie.dmac_laddress + ofst;
3404 3393 mcp->mb[10] = MSW(LSD(addr));
3405 3394 mcp->mb[11] = LSW(LSD(addr));
3406 3395 mcp->mb[12] = MSW(MSD(addr));
3407 3396 mcp->mb[13] = LSW(MSD(addr));
3408 3397 mcp->mb[14] = sizeof (ql_ext_icb_8100_t);
3409 3398 mcp->mb[1] = BIT_0;
3410 3399 }
3411 3400 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
3412 3401 MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3413 3402 } else {
3414 3403 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3415 3404 }
3416 3405 mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0;
3417 3406 mcp->timeout = MAILBOX_TOV;
3418 3407 rval = ql_mailbox_command(ha, mcp);
3419 3408
3420 3409 if (rval == QL_SUCCESS) {
3421 3410 ha->sfp_stat = mcp->mb[2];
3422 3411 }
3423 3412 ql_free_dma_resource(ha, &mem_desc);
3424 3413
3425 3414 if (rval != QL_SUCCESS) {
3426 3415 EL(ha, "failed=%xh\n", rval);
3427 3416 } else {
3428 3417 /*EMPTY*/
3429 3418 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3430 3419 }
3431 3420
3432 3421 return (rval);
3433 3422 }
3434 3423
3435 3424 /*
3436 3425 * ql_get_firmware_state
3437 3426 * Get adapter firmware state.
3438 3427 *
3439 3428 * Input:
3440 3429 * ha: adapter state pointer.
3441 3430 * mr: pointer for mailbox data.
3442 3431 *
3443 3432 * Returns:
3444 3433 * ql local function return status code.
3445 3434 *
3446 3435 * Context:
3447 3436 * Kernel context.
3448 3437 */
3449 3438 int
3450 3439 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3451 3440 {
3452 3441 int rval;
3453 3442 mbx_cmd_t mc = {0};
3454 3443 mbx_cmd_t *mcp = &mc;
3455 3444
3456 3445 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3457 3446
3458 3447 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3459 3448 mcp->out_mb = MBX_0;
3460 3449 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3461 3450 mcp->timeout = MAILBOX_TOV;
3462 3451 rval = ql_mailbox_command(ha, mcp);
3463 3452
3464 3453 /* Return mailbox data. */
3465 3454 if (mr != NULL) {
3466 3455 mr->mb[1] = mcp->mb[1];
3467 3456 mr->mb[2] = mcp->mb[2];
3468 3457 mr->mb[3] = mcp->mb[3];
3469 3458 mr->mb[4] = mcp->mb[4];
3470 3459 mr->mb[5] = mcp->mb[5];
3471 3460 }
3472 3461
3473 3462 ha->sfp_stat = mcp->mb[2];
3474 3463
3475 3464 if (rval != QL_SUCCESS) {
3476 3465 EL(ha, "failed=%xh\n", rval);
3477 3466 } else {
3478 3467 /*EMPTY*/
3479 3468 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3480 3469 }
3481 3470
3482 3471 return (rval);
3483 3472 }
3484 3473
3485 3474 /*
3486 3475 * ql_get_adapter_id
3487 3476 * Get adapter ID and topology.
3488 3477 *
3489 3478 * Input:
3490 3479 * ha: adapter state pointer.
3491 3480 * mr: pointer for mailbox data.
3492 3481 *
3493 3482 * Returns:
3494 3483 * ql local function return status code.
3495 3484 *
3496 3485 * Context:
3497 3486 * Kernel context.
3498 3487 */
3499 3488 int
3500 3489 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3501 3490 {
3502 3491 int rval;
3503 3492 mbx_cmd_t mc = {0};
3504 3493 mbx_cmd_t *mcp = &mc;
3505 3494
3506 3495 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3507 3496
3508 3497 mcp->mb[0] = MBC_GET_ID;
3509 3498 if (ha->flags & VP_ENABLED) {
3510 3499 mcp->mb[9] = ha->vp_index;
3511 3500 }
3512 3501 mcp->out_mb = MBX_9|MBX_0;
3513 3502 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|
3514 3503 MBX_3|MBX_2|MBX_1|MBX_0;
3515 3504 mcp->timeout = MAILBOX_TOV;
3516 3505
3517 3506 rval = ql_mailbox_command(ha, mcp);
3518 3507
3519 3508 /* Return mailbox data. */
3520 3509 if (mr != NULL) {
3521 3510 mr->mb[1] = mcp->mb[1];
3522 3511 mr->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
3523 3512 0xffff : mcp->mb[1]);
3524 3513 mr->mb[2] = mcp->mb[2];
3525 3514 mr->mb[3] = mcp->mb[3];
3526 3515 mr->mb[6] = mcp->mb[6];
3527 3516 mr->mb[7] = mcp->mb[7];
3528 3517 mr->mb[8] = mcp->mb[8];
3529 3518 mr->mb[9] = mcp->mb[9];
3530 3519 mr->mb[10] = mcp->mb[10];
3531 3520 mr->mb[11] = mcp->mb[11];
3532 3521 mr->mb[12] = mcp->mb[12];
3533 3522 mr->mb[13] = mcp->mb[13];
3534 3523 }
3535 3524
3536 3525 if (rval != QL_SUCCESS) {
3537 3526 EL(ha, "failed=%xh\n", rval);
3538 3527 } else {
3539 3528 /*EMPTY*/
3540 3529 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3541 3530 }
3542 3531
3543 3532 return (rval);
3544 3533 }
3545 3534
3546 3535 /*
3547 3536 * ql_get_fw_version
3548 3537 * Get firmware version.
3549 3538 *
3550 3539 * Input:
3551 3540 * ha: adapter state pointer.
3552 3541 * mr: pointer for mailbox data.
3553 3542 *
3554 3543 * Returns:
3555 3544 * ql local function return status code.
3556 3545 *
3557 3546 * Context:
3558 3547 * Kernel context.
3559 3548 */
3560 3549 int
3561 3550 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout)
3562 3551 {
3563 3552 int rval;
3564 3553 mbx_cmd_t mc = {0};
3565 3554 mbx_cmd_t *mcp = &mc;
3566 3555
3567 3556 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3568 3557
3569 3558 mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3570 3559 mcp->out_mb = MBX_0;
3571 3560 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_6|MBX_5|
3572 3561 MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3573 3562 mcp->timeout = timeout;
3574 3563 rval = ql_mailbox_command(ha, mcp);
3575 3564
3576 3565 /* Return mailbox data. */
3577 3566 if (mr != NULL) {
3578 3567 mr->mb[1] = mcp->mb[1];
3579 3568 mr->mb[2] = mcp->mb[2];
3580 3569 mr->mb[3] = mcp->mb[3];
3581 3570 mr->mb[4] = mcp->mb[4];
3582 3571 mr->mb[5] = mcp->mb[5];
3583 3572 mr->mb[6] = mcp->mb[6];
3584 3573 mr->mb[8] = mcp->mb[8];
3585 3574 mr->mb[9] = mcp->mb[9];
3586 3575 mr->mb[10] = mcp->mb[10];
3587 3576 mr->mb[11] = mcp->mb[11];
3588 3577 mr->mb[12] = mcp->mb[12];
3589 3578 mr->mb[13] = mcp->mb[13];
3590 3579 }
3591 3580
3592 3581 if (rval != QL_SUCCESS) {
3593 3582 EL(ha, "failed=%xh\n", rval);
3594 3583 } else {
3595 3584 /*EMPTY*/
3596 3585 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3597 3586 }
3598 3587
3599 3588 return (rval);
3600 3589 }
3601 3590
3602 3591 /*
3603 3592 * ql_data_rate
3604 3593 * Issue data rate Mailbox Command.
3605 3594 *
3606 3595 * Input:
3607 3596 * ha: adapter state pointer.
3608 3597 * mr: pointer for mailbox data.
3609 3598 *
3610 3599 * Returns:
3611 3600 * ql local function return status code.
3612 3601 *
3613 3602 * Context:
3614 3603 * Kernel context.
3615 3604 */
3616 3605 int
3617 3606 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3618 3607 {
3619 3608 int rval;
3620 3609 mbx_cmd_t mc = {0};
3621 3610 mbx_cmd_t *mcp = &mc;
3622 3611
3623 3612 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3624 3613
3625 3614 if (mr != NULL) {
3626 3615 mcp->mb[0] = MBC_DATA_RATE;
3627 3616 mcp->mb[1] = mr->mb[1];
3628 3617 mcp->mb[2] = mr->mb[2];
3629 3618 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3630 3619 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3631 3620 mcp->timeout = MAILBOX_TOV;
3632 3621 rval = ql_mailbox_command(ha, mcp);
3633 3622
3634 3623 /* Return mailbox data. */
3635 3624 mr->mb[1] = mcp->mb[1];
3636 3625 mr->mb[2] = mcp->mb[2];
3637 3626 } else {
3638 3627 rval = QL_FUNCTION_PARAMETER_ERROR;
3639 3628 }
3640 3629
3641 3630 ha->sfp_stat = mcp->mb[2];
3642 3631
3643 3632 if (rval != QL_SUCCESS) {
3644 3633 EL(ha, "failed=%xh\n", rval);
3645 3634 } else {
3646 3635 /*EMPTY*/
3647 3636 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3648 3637 }
3649 3638
3650 3639 return (rval);
3651 3640 }
3652 3641
3653 3642 /*
3654 3643 * ql_Diag_Loopback
3655 3644 * Issue Reset Link Status mailbox command
3656 3645 *
3657 3646 * Input:
3658 3647 * ha: adapter state pointer.
3659 3648 * findex: FCF index.
3660 3649 * bp: buffer pointer.
3661 3650 * size: buffer size.
3662 3651 * opt: command options.
3663 3652 * it_cnt: iteration count.
3664 3653 * mr: pointer for mailbox data.
3665 3654 *
3666 3655 * Returns:
3667 3656 * ql local function return status code.
3668 3657 *
3669 3658 * Context:
3670 3659 * Kernel context.
3671 3660 */
3672 3661 int
3673 3662 ql_diag_loopback(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp,
3674 3663 uint32_t size, uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3675 3664 {
3676 3665 int rval;
3677 3666 dma_mem_t mem_desc;
3678 3667 mbx_cmd_t mc = {0};
3679 3668 mbx_cmd_t *mcp = &mc;
3680 3669
3681 3670 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3682 3671
3683 3672 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3684 3673 QL_SUCCESS) {
3685 3674 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3686 3675 return (rval);
3687 3676 }
3688 3677
3689 3678 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3690 3679 mcp->mb[1] = opt;
3691 3680 mcp->mb[2] = findex;
3692 3681 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3693 3682 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3694 3683 mcp->mb[10] = LSW(size);
3695 3684 mcp->mb[11] = MSW(size);
3696 3685 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3697 3686 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3698 3687 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3699 3688 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3700 3689 mcp->mb[18] = LSW(it_cnt);
3701 3690 mcp->mb[19] = MSW(it_cnt);
3702 3691 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3703 3692 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3704 3693 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3705 3694 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3706 3695 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3707 3696 mcp->timeout = it_cnt / 300;
3708 3697 if (mcp->timeout < MAILBOX_TOV) {
3709 3698 mcp->timeout = MAILBOX_TOV;
3710 3699 }
3711 3700 rval = ql_mailbox_command(ha, mcp);
3712 3701
3713 3702 if (rval == QL_SUCCESS) {
3714 3703 ql_get_mbox_dma_data(&mem_desc, bp);
3715 3704 }
3716 3705
3717 3706 ql_free_dma_resource(ha, &mem_desc);
3718 3707
3719 3708 /* Return mailbox data. */
3720 3709 if (mr != NULL) {
3721 3710 mr->mb[0] = mcp->mb[0];
3722 3711 mr->mb[1] = mcp->mb[1];
3723 3712 mr->mb[2] = mcp->mb[2];
3724 3713 mr->mb[3] = mcp->mb[3];
3725 3714 mr->mb[18] = mcp->mb[18];
3726 3715 mr->mb[19] = mcp->mb[19];
3727 3716 }
3728 3717
3729 3718 if (rval != QL_SUCCESS) {
3730 3719 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3731 3720 } else {
3732 3721 /*EMPTY*/
3733 3722 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3734 3723 }
3735 3724
3736 3725 return (rval);
3737 3726 }
3738 3727
3739 3728 /*
3740 3729 * ql_diag_echo
3741 3730 * Issue Diag echo mailbox command. Valid for qla23xx HBA's.
3742 3731 *
3743 3732 * Input:
3744 3733 * ha: adapter state pointer.
3745 3734 * findex: FCF index.
3746 3735 * bp: buffer pointer.
3747 3736 * size: buffer size.
3748 3737 * opt: command options.
3749 3738 * mr: pointer to mailbox status.
3750 3739 *
3751 3740 * Returns:
3752 3741 * ql local function return status code.
3753 3742 *
3754 3743 * Context:
3755 3744 * Kernel context.
3756 3745 */
3757 3746 int
3758 3747 ql_diag_echo(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp,
3759 3748 uint32_t size, uint16_t opt, ql_mbx_data_t *mr)
3760 3749 {
3761 3750 int rval;
3762 3751 dma_mem_t mem_desc;
3763 3752 mbx_cmd_t mc = {0};
3764 3753 mbx_cmd_t *mcp = &mc;
3765 3754
3766 3755 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3767 3756
3768 3757 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3769 3758 QL_SUCCESS) {
3770 3759 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3771 3760 return (rval);
3772 3761 }
3773 3762
3774 3763 mcp->mb[0] = MBC_ECHO;
3775 3764 mcp->mb[1] = opt;
3776 3765 mcp->mb[2] = findex;
3777 3766 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3778 3767 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3779 3768 mcp->mb[10] = LSW(size);
3780 3769 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3781 3770 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3782 3771 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3783 3772 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3784 3773 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3785 3774 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3786 3775 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3787 3776 MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3788 3777 mcp->in_mb = MBX_1|MBX_0;
3789 3778 mcp->timeout = MAILBOX_TOV;
3790 3779 rval = ql_mailbox_command(ha, mcp);
3791 3780
3792 3781 if (rval == QL_SUCCESS) {
3793 3782 ql_get_mbox_dma_data(&mem_desc, bp);
3794 3783 }
3795 3784
3796 3785 ql_free_dma_resource(ha, &mem_desc);
3797 3786
3798 3787 if (mr != NULL) {
3799 3788 mr->mb[0] = mcp->mb[0];
3800 3789 }
3801 3790
3802 3791 if (rval != QL_SUCCESS) {
3803 3792 EL(ha, "failed=%xh, mb1=%xh\n", rval,
3804 3793 mcp->mb[1]);
3805 3794 } else {
3806 3795 /*EMPTY*/
3807 3796 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3808 3797 }
3809 3798
3810 3799 return (rval);
3811 3800 }
3812 3801
3813 3802 /*
3814 3803 * ql_serdes_param
3815 3804 * Set/Get serdes transmit parameters mailbox command.
3816 3805 *
3817 3806 * Input:
3818 3807 * ha: adapter state pointer.
3819 3808 * mr: pointer to mailbox in/out parameters.
3820 3809 *
3821 3810 * Returns:
3822 3811 * ql local function return status code.
3823 3812 *
3824 3813 * Context:
3825 3814 * Kernel context.
3826 3815 */
3827 3816 int
3828 3817 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3829 3818 {
3830 3819 int rval;
3831 3820 mbx_cmd_t mc = {0};
3832 3821 mbx_cmd_t *mcp = &mc;
3833 3822
3834 3823 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3835 3824
3836 3825 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
3837 3826 mcp->mb[1] = mr->mb[1];
3838 3827 mcp->mb[2] = mr->mb[2];
3839 3828 mcp->mb[3] = mr->mb[3];
3840 3829 mcp->mb[4] = mr->mb[4];
3841 3830 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3842 3831 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
3843 3832 mcp->timeout = MAILBOX_TOV;
3844 3833 rval = ql_mailbox_command(ha, mcp);
3845 3834
3846 3835 /* Return mailbox data. */
3847 3836 if (mr != NULL) {
3848 3837 mr->mb[0] = mcp->mb[0];
3849 3838 mr->mb[2] = mcp->mb[2];
3850 3839 mr->mb[3] = mcp->mb[3];
3851 3840 mr->mb[4] = mcp->mb[4];
3852 3841 }
3853 3842
3854 3843 if (rval != QL_SUCCESS) {
3855 3844 EL(ha, "failed=%xh\n", rval);
3856 3845 } else {
3857 3846 /*EMPTY*/
3858 3847 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3859 3848 }
3860 3849
3861 3850 return (rval);
3862 3851 }
3863 3852
3864 3853 /*
3865 3854 * ql_get_timeout_parameters
3866 3855 * Issue get timeout parameters mailbox command.
3867 3856 *
3868 3857 * Input:
3869 3858 * ha: adapter state pointer.
3870 3859 * mr: pointer to mailbox in/out parameters.
3871 3860 *
3872 3861 * Returns:
3873 3862 * ql local function return status code.
3874 3863 *
3875 3864 * Context:
3876 3865 * Kernel context.
3877 3866 */
3878 3867 int
3879 3868 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
3880 3869 {
3881 3870 int rval;
3882 3871 mbx_cmd_t mc = {0};
3883 3872 mbx_cmd_t *mcp = &mc;
3884 3873
3885 3874 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3886 3875
3887 3876 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
3888 3877 mcp->out_mb = MBX_0;
3889 3878 mcp->in_mb = MBX_3|MBX_0;
3890 3879 mcp->timeout = MAILBOX_TOV;
3891 3880 rval = ql_mailbox_command(ha, mcp);
3892 3881 if (rval == QL_SUCCESS) {
3893 3882 /* Get 2 * R_A_TOV in seconds */
3894 3883 if (CFG_IST(ha, CFG_CTRL_2200) || mcp->mb[3] == 0) {
3895 3884 *tov = R_A_TOV_DEFAULT;
3896 3885 } else {
3897 3886 *tov = (uint16_t)(mcp->mb[3] / 10);
3898 3887 if (mcp->mb[3] % 10 != 0) {
3899 3888 *tov = (uint16_t)(*tov + 1);
3900 3889 }
3901 3890 /*
3902 3891 * Adjust value to prevent driver timeout at the same
3903 3892 * time as device.
3904 3893 */
3905 3894 *tov = (uint16_t)(*tov + 5);
3906 3895 }
3907 3896 } else {
3908 3897 *tov = R_A_TOV_DEFAULT;
3909 3898 }
3910 3899
3911 3900 if (rval != QL_SUCCESS) {
3912 3901 EL(ha, "failed=%xh\n", rval);
3913 3902 } else {
3914 3903 /*EMPTY*/
3915 3904 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3916 3905 }
3917 3906
3918 3907 return (rval);
3919 3908 }
3920 3909
3921 3910 /*
3922 3911 * ql_stop_firmware
3923 3912 * Issue stop firmware Mailbox Command.
3924 3913 *
3925 3914 * Input:
3926 3915 * ha: adapter state pointer.
3927 3916 *
3928 3917 * Returns:
3929 3918 * ql local function return status code.
3930 3919 *
3931 3920 * Context:
3932 3921 * Kernel context.
3933 3922 */
3934 3923 int
3935 3924 ql_stop_firmware(ql_adapter_state_t *ha)
3936 3925 {
3937 3926 int rval;
3938 3927 mbx_cmd_t mc = {0};
3939 3928 mbx_cmd_t *mcp = &mc;
3940 3929
3941 3930 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3942 3931
3943 3932 mcp->mb[0] = MBC_STOP_FIRMWARE;
3944 3933 mcp->out_mb = MBX_1|MBX_0;
3945 3934 mcp->in_mb = MBX_0;
3946 3935 mcp->timeout = 2;
3947 3936 rval = ql_mailbox_command(ha, mcp);
3948 3937
3949 3938 if (rval != QL_SUCCESS) {
3950 3939 EL(ha, "failed=%xh\n", rval);
3951 3940 } else {
3952 3941 /*EMPTY*/
3953 3942 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3954 3943 }
3955 3944
3956 3945 return (rval);
3957 3946 }
3958 3947
3959 3948 /*
3960 3949 * ql_read_sfp
3961 3950 * Issue Read SFP Mailbox command
3962 3951 *
3963 3952 * Input:
3964 3953 * ha: adapter state pointer.
3965 3954 * mem: pointer to dma memory object for command.
3966 3955 * dev: Device address (A0h or A2h).
3967 3956 * addr: Data address on SFP EEPROM (0–255).
3968 3957 *
3969 3958 * Returns:
3970 3959 * ql local function return status code.
3971 3960 *
3972 3961 * Context:
3973 3962 * Kernel context.
3974 3963 */
3975 3964 int
3976 3965 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
3977 3966 uint16_t addr)
3978 3967 {
3979 3968 int rval;
3980 3969 mbx_cmd_t mc = {0};
3981 3970 mbx_cmd_t *mcp = &mc;
3982 3971
3983 3972 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3984 3973
3985 3974 mcp->mb[0] = MBC_READ_SFP;
3986 3975 mcp->mb[1] = dev;
3987 3976 mcp->mb[2] = MSW(mem->cookies->dmac_address);
3988 3977 mcp->mb[3] = LSW(mem->cookies->dmac_address);
3989 3978 mcp->mb[6] = MSW(mem->cookies->dmac_notused);
3990 3979 mcp->mb[7] = LSW(mem->cookies->dmac_notused);
3991 3980 mcp->mb[8] = LSW(mem->size);
3992 3981 mcp->mb[9] = addr;
3993 3982 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3994 3983 mcp->in_mb = MBX_1|MBX_0;
3995 3984 mcp->timeout = MAILBOX_TOV;
3996 3985 rval = ql_mailbox_command(ha, mcp);
3997 3986
3998 3987 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
3999 3988 DDI_DMA_SYNC_FORKERNEL);
4000 3989
4001 3990 if (rval != QL_SUCCESS) {
4002 3991 EL(ha, "failed=%xh\n", rval);
4003 3992 } else {
4004 3993 /*EMPTY*/
4005 3994 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4006 3995 }
4007 3996
4008 3997 return (rval);
4009 3998 }
4010 3999
4011 4000 /*
4012 4001 * ql_iidma_rate
4013 4002 * Issue get/set iidma rate command
4014 4003 *
4015 4004 * Input:
4016 4005 * ha: adapter state pointer.
4017 4006 * loop_id: n-port handle to set/get iidma rate.
4018 4007 * idma_rate: Pointer to iidma rate.
4019 4008 * option: iidma firmware option (set or get data).
4020 4009 * 0 --> Get iidma rate
4021 4010 * 1 --> Set iidma rate
4022 4011 *
4023 4012 * Returns:
4024 4013 * ql local function return status code.
4025 4014 *
4026 4015 * Context:
4027 4016 * Kernel context.
4028 4017 */
4029 4018 int
4030 4019 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
4031 4020 uint32_t option)
4032 4021 {
4033 4022 int rval;
4034 4023 mbx_cmd_t mc = {0};
4035 4024 mbx_cmd_t *mcp = &mc;
4036 4025
4037 4026 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4038 4027
4039 4028 mcp->mb[0] = MBC_PORT_PARAM;
4040 4029 mcp->mb[1] = loop_id;
4041 4030 mcp->mb[2] = (uint16_t)option;
4042 4031 mcp->out_mb = MBX_0|MBX_1|MBX_2;
4043 4032 mcp->in_mb = MBX_0|MBX_1;
4044 4033
4045 4034 if (option & BIT_0) {
4046 4035 mcp->mb[3] = (uint16_t)*idma_rate;
4047 4036 mcp->out_mb |= MBX_3;
4048 4037 } else {
4049 4038 mcp->in_mb |= MBX_3;
4050 4039 }
4051 4040
4052 4041 mcp->timeout = MAILBOX_TOV;
4053 4042 rval = ql_mailbox_command(ha, mcp);
4054 4043
4055 4044 if (rval != QL_SUCCESS) {
4056 4045 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
4057 4046 } else {
4058 4047 if (option == 0) {
4059 4048 *idma_rate = mcp->mb[3];
4060 4049 }
4061 4050
4062 4051 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4063 4052 }
4064 4053
4065 4054 return (rval);
4066 4055 }
4067 4056
4068 4057 /*
4069 4058 * ql_set_xmit_parms
4070 4059 * Set transmit parameters
4071 4060 *
4072 4061 * Input:
4073 4062 * ha: adapter state pointer.
4074 4063 *
4075 4064 * Returns:
4076 4065 * ql local function return status code.
4077 4066 *
4078 4067 * Context:
4079 4068 * Kernel context.
4080 4069 */
4081 4070 int
4082 4071 ql_set_xmit_parms(ql_adapter_state_t *ha)
4083 4072 {
4084 4073 int rval;
4085 4074 mbx_cmd_t mc = {0};
4086 4075 mbx_cmd_t *mcp = &mc;
4087 4076
4088 4077 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4089 4078
4090 4079 mcp->mb[0] = MBC_XMIT_PARM;
4091 4080 mcp->mb[1] = BIT_1;
4092 4081 mcp->out_mb = MBX_1|MBX_0;
4093 4082 mcp->in_mb = MBX_0;
4094 4083 mcp->timeout = MAILBOX_TOV;
4095 4084 rval = ql_mailbox_command(ha, mcp);
4096 4085
4097 4086 if (rval != QL_SUCCESS) {
4098 4087 EL(ha, "failed=%xh\n", rval);
4099 4088 } else {
4100 4089 /*EMPTY*/
4101 4090 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4102 4091 }
4103 4092 return (rval);
4104 4093 }
4105 4094
4106 4095 /*
4107 4096 * ql_fw_etrace
4108 4097 * Firmware extended tracing.
4109 4098 *
4110 4099 * Input:
4111 4100 * ha: adapter state pointer.
4112 4101 * mem: pointer to dma memory object for command.
4113 4102 * opt: options and opcode.
4114 4103 *
4115 4104 * Returns:
4116 4105 * ql local function return status code.
4117 4106 *
4118 4107 * Context:
4119 4108 * Kernel context.
4120 4109 */
4121 4110 int
4122 4111 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt)
4123 4112 {
4124 4113 int rval = QL_SUCCESS;
4125 4114 mbx_cmd_t mc = {0};
4126 4115 mbx_cmd_t *mcp = &mc;
4127 4116 uint16_t op_code;
4128 4117 uint64_t time;
4129 4118
4130 4119 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4131 4120
4132 4121 /* currently no supported options */
4133 4122 op_code = (uint16_t)(opt & ~0xFF00);
4134 4123
4135 4124 mcp->mb[0] = MBC_TRACE_CONTROL;
4136 4125 mcp->mb[1] = op_code;
4137 4126 mcp->in_mb = MBX_0;
4138 4127 mcp->timeout = MAILBOX_TOV;
4139 4128
4140 4129 switch (op_code) {
4141 4130 case FTO_INSERT_TIME_STAMP:
4142 4131
4143 4132 (void) drv_getparm(TIME, &time);
4144 4133
4145 4134 EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
4146 4135
4147 4136 mcp->mb[2] = LSW(LSD(time));
4148 4137 mcp->mb[3] = MSW(LSD(time));
4149 4138 mcp->mb[4] = LSW(MSD(time));
4150 4139 mcp->mb[5] = MSW(MSD(time));
4151 4140 mcp->out_mb = MBX_0_THRU_5;
4152 4141 break;
4153 4142
4154 4143 case FTO_FCE_TRACE_ENABLE:
4155 4144 /* Firmware Fibre Channel Event Trace Buffer */
4156 4145 mcp->mb[2] = LSW(mem->cookies->dmac_address);
4157 4146 mcp->mb[3] = MSW(mem->cookies->dmac_address);
4158 4147 mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4159 4148 mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4160 4149 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
4161 4150 mcp->mb[8] = (uint16_t)ha->fwfcetraceopt;
4162 4151 mcp->mb[9] = FTO_FCEMAXTRACEBUF;
4163 4152 mcp->mb[10] = FTO_FCEMAXTRACEBUF;
4164 4153 mcp->out_mb = MBX_0_THRU_10;
4165 4154 break;
4166 4155
4167 4156 case FTO_EXT_TRACE_ENABLE:
4168 4157 /* Firmware Extended Trace Buffer */
4169 4158 mcp->mb[2] = LSW(mem->cookies->dmac_address);
4170 4159 mcp->mb[3] = MSW(mem->cookies->dmac_address);
4171 4160 mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4172 4161 mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4173 4162 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
4174 4163 mcp->out_mb = MBX_0_THRU_7;
4175 4164 break;
4176 4165
4177 4166 case FTO_FCE_TRACE_DISABLE:
4178 4167 /* also causes ISP25xx to flush its internal FCE buffer. */
4179 4168 mcp->mb[2] = BIT_0;
4180 4169 mcp->out_mb = MBX_0_THRU_2;
4181 4170 break;
4182 4171
4183 4172 case FTO_EXT_TRACE_DISABLE:
4184 4173 /* just sending the opcode disables it */
4185 4174 break;
4186 4175
4187 4176 default:
4188 4177 EL(ha, "invalid option: %xh\n", opt);
4189 4178 rval = QL_PARAMETER_ERROR;
4190 4179 break;
4191 4180 }
4192 4181
4193 4182 if (rval == QL_SUCCESS) {
4194 4183 rval = ql_mailbox_command(ha, mcp);
4195 4184 }
4196 4185
4197 4186 if (rval != QL_SUCCESS) {
4198 4187 EL(ha, "failed=%xh\n", rval);
4199 4188 } else {
4200 4189 /*EMPTY*/
4201 4190 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4202 4191 }
4203 4192
4204 4193 return (rval);
4205 4194 }
4206 4195
4207 4196 /*
4208 4197 * ql_reset_menlo
4209 4198 * Reset Menlo Mailbox Command.
4210 4199 *
4211 4200 * Input:
4212 4201 * ha: adapter state pointer.
4213 4202 * mr: pointer to mailbox in/out parameters.
4214 4203 * opt: options.
4215 4204 *
4216 4205 * Returns:
4217 4206 * ql local function return status code.
4218 4207 *
4219 4208 * Context:
4220 4209 * Kernel context.
4221 4210 */
4222 4211 int
4223 4212 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4224 4213 {
4225 4214 int rval;
4226 4215 mbx_cmd_t mc = {0};
4227 4216 mbx_cmd_t *mcp = &mc;
4228 4217
4229 4218 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4230 4219
4231 4220 mcp->mb[0] = MBC_RESET_MENLO;
4232 4221 mcp->mb[1] = opt;
4233 4222 mcp->out_mb = MBX_1|MBX_0;
4234 4223 mcp->in_mb = MBX_1|MBX_0;
4235 4224 mcp->timeout = MAILBOX_TOV;
4236 4225 rval = ql_mailbox_command(ha, mcp);
4237 4226
4238 4227 /* Return mailbox data. */
4239 4228 if (mr != NULL) {
4240 4229 mr->mb[0] = mcp->mb[0];
4241 4230 mr->mb[1] = mcp->mb[1];
4242 4231 }
4243 4232
4244 4233 if (rval != QL_SUCCESS) {
4245 4234 EL(ha, "failed=%xh\n", rval);
4246 4235 } else {
4247 4236 /*EMPTY*/
4248 4237 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4249 4238 }
4250 4239
4251 4240 return (rval);
4252 4241 }
4253 4242
4254 4243 /*
4255 4244 * ql_restart_mpi
4256 4245 * The Restart MPI Firmware Mailbox Command will reset the MPI RISC,
4257 4246 * reload MPI firmware from Flash, and execute the firmware.
4258 4247 *
4259 4248 * Input:
4260 4249 * ha: adapter state pointer.
4261 4250 *
4262 4251 * Returns:
4263 4252 * ql local function return status code.
4264 4253 *
4265 4254 * Context:
4266 4255 * Kernel context.
4267 4256 */
4268 4257 int
4269 4258 ql_restart_mpi(ql_adapter_state_t *ha)
4270 4259 {
4271 4260 int rval;
4272 4261 mbx_cmd_t mc = {0};
4273 4262 mbx_cmd_t *mcp = &mc;
4274 4263
4275 4264 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4276 4265
4277 4266 mcp->mb[0] = MBC_RESTART_MPI;
4278 4267 mcp->out_mb = MBX_0;
4279 4268 mcp->in_mb = MBX_1|MBX_0;
4280 4269 mcp->timeout = MAILBOX_TOV;
4281 4270 rval = ql_mailbox_command(ha, mcp);
4282 4271
4283 4272 /* Return mailbox data. */
4284 4273 if (rval != QL_SUCCESS) {
4285 4274 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
4286 4275 } else {
4287 4276 /*EMPTY*/
4288 4277 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4289 4278 }
4290 4279
4291 4280 return (rval);
4292 4281 }
4293 4282
4294 4283 /*
4295 4284 * ql_idc_request
4296 4285 * Inter-Driver Communication Request.
4297 4286 *
4298 4287 * Input:
4299 4288 * ha: adapter state pointer.
4300 4289 * mr: pointer for mailbox data.
4301 4290 *
4302 4291 * Returns:
4303 4292 * ql local function return status code.
4304 4293 *
4305 4294 * Context:
4306 4295 * Kernel context.
4307 4296 */
4308 4297 int
4309 4298 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4310 4299 {
4311 4300 int rval;
4312 4301 mbx_cmd_t mc = {0};
4313 4302 mbx_cmd_t *mcp = &mc;
4314 4303
4315 4304 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4316 4305
4317 4306 mcp->mb[0] = MBC_IDC_REQUEST;
4318 4307 mcp->mb[1] = mr->mb[1];
4319 4308 mcp->mb[2] = mr->mb[2];
4320 4309 mcp->mb[3] = mr->mb[3];
4321 4310 mcp->mb[4] = mr->mb[4];
4322 4311 mcp->mb[5] = mr->mb[5];
4323 4312 mcp->mb[6] = mr->mb[6];
4324 4313 mcp->mb[7] = mr->mb[7];
4325 4314 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4326 4315 mcp->in_mb = MBX_2|MBX_0;
4327 4316 mcp->timeout = MAILBOX_TOV;
4328 4317 rval = ql_mailbox_command(ha, mcp);
4329 4318
4330 4319 if (rval == QL_SUCCESS) {
4331 4320 if (mr != NULL) {
4332 4321 mr->mb[2] = mcp->mb[2];
4333 4322 }
4334 4323 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4335 4324 } else {
4336 4325 EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]);
4337 4326 }
4338 4327
4339 4328 return (rval);
4340 4329 }
4341 4330
4342 4331 /*
4343 4332 * ql_idc_ack
4344 4333 * Inter-Driver Communication Acknowledgement.
4345 4334 *
4346 4335 * Input:
4347 4336 * ha: adapter state pointer.
4348 4337 *
4349 4338 * Returns:
4350 4339 * ql local function return status code.
4351 4340 *
4352 4341 * Context:
4353 4342 * Kernel context.
4354 4343 */
4355 4344 int
4356 4345 ql_idc_ack(ql_adapter_state_t *ha)
4357 4346 {
4358 4347 int rval;
4359 4348 mbx_cmd_t mc = {0};
4360 4349 mbx_cmd_t *mcp = &mc;
4361 4350
4362 4351 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4363 4352
4364 4353 mcp->mb[0] = MBC_IDC_ACK;
4365 4354 mcp->mb[1] = ha->idc_mb[1];
4366 4355 mcp->mb[2] = ha->idc_mb[2];
4367 4356 mcp->mb[3] = ha->idc_mb[3];
4368 4357 mcp->mb[4] = ha->idc_mb[4];
4369 4358 mcp->mb[5] = ha->idc_mb[5];
4370 4359 mcp->mb[6] = ha->idc_mb[6];
4371 4360 mcp->mb[7] = ha->idc_mb[7];
4372 4361 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4373 4362 mcp->in_mb = MBX_0;
4374 4363 mcp->timeout = MAILBOX_TOV;
4375 4364 rval = ql_mailbox_command(ha, mcp);
4376 4365
4377 4366 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4378 4367
4379 4368 return (rval);
4380 4369 }
4381 4370
4382 4371 /*
4383 4372 * ql_idc_time_extend
4384 4373 * Inter-Driver Communication Time Extend
4385 4374 *
4386 4375 * Input:
4387 4376 * ha: adapter state pointer.
4388 4377 * mr: pointer for mailbox data.
4389 4378 *
4390 4379 * Returns:
4391 4380 * ql local function return status code.
4392 4381 *
4393 4382 * Context:
4394 4383 * Kernel context.
4395 4384 */
4396 4385 int
4397 4386 ql_idc_time_extend(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4398 4387 {
4399 4388 int rval;
4400 4389 mbx_cmd_t mc = {0};
4401 4390 mbx_cmd_t *mcp = &mc;
4402 4391
4403 4392 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4404 4393
4405 4394 mcp->mb[0] = MBC_IDC_TIME_EXTEND;
4406 4395 mcp->mb[1] = mr->mb[1];
4407 4396 mcp->mb[2] = mr->mb[2];
4408 4397 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4409 4398 mcp->in_mb = MBX_0;
4410 4399 mcp->timeout = MAILBOX_TOV;
4411 4400 rval = ql_mailbox_command(ha, mcp);
4412 4401
4413 4402 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4414 4403
4415 4404 return (rval);
4416 4405 }
4417 4406
4418 4407 /*
4419 4408 * ql_port_reset
4420 4409 * The Port Reset for the external 10G port associated with this function.
4421 4410 *
4422 4411 * Input:
4423 4412 * ha: adapter state pointer.
4424 4413 *
4425 4414 * Returns:
4426 4415 * ql local function return status code.
4427 4416 *
4428 4417 * Context:
4429 4418 * Kernel context.
4430 4419 */
4431 4420 int
4432 4421 ql_port_reset(ql_adapter_state_t *ha)
4433 4422 {
4434 4423 int rval;
4435 4424 mbx_cmd_t mc = {0};
4436 4425 mbx_cmd_t *mcp = &mc;
4437 4426
4438 4427 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4439 4428
4440 4429 mcp->mb[0] = MBC_PORT_RESET;
4441 4430 mcp->out_mb = MBX_0;
4442 4431 mcp->in_mb = MBX_0;
4443 4432 mcp->timeout = MAILBOX_TOV;
4444 4433 rval = ql_mailbox_command(ha, mcp);
4445 4434
4446 4435 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4447 4436
4448 4437 return (rval);
4449 4438 }
4450 4439
4451 4440 /*
4452 4441 * ql_set_port_config
4453 4442 * The Set Port Configuration command sets the configuration for the
4454 4443 * external 10G port associated with this function.
4455 4444 *
4456 4445 * Input:
4457 4446 * ha: adapter state pointer.
4458 4447 * mr: pointer for mailbox data.
4459 4448 *
4460 4449 * Returns:
4461 4450 * ql local function return status code.
4462 4451 *
4463 4452 * Context:
4464 4453 * Kernel context.
4465 4454 */
4466 4455 int
4467 4456 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4468 4457 {
4469 4458 int rval;
4470 4459 mbx_cmd_t mc = {0};
4471 4460 mbx_cmd_t *mcp = &mc;
4472 4461
4473 4462 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4474 4463
4475 4464 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4476 4465 mcp->mb[1] = mrp->mb[1];
4477 4466 mcp->mb[2] = mrp->mb[2];
4478 4467 mcp->mb[3] = mrp->mb[3];
4479 4468 mcp->mb[4] = mrp->mb[4];
4480 4469 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4481 4470 mcp->in_mb = MBX_0;
4482 4471 mcp->timeout = MAILBOX_TOV;
4483 4472 rval = ql_mailbox_command(ha, mcp);
4484 4473
4485 4474 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4486 4475
4487 4476 return (rval);
4488 4477 }
4489 4478
4490 4479 /*
4491 4480 * ql_get_port_config
4492 4481 * The Get Port Configuration command retrieves the current configuration
4493 4482 * for the external 10G port associated with this function.
4494 4483 *
4495 4484 * Input:
4496 4485 * ha: adapter state pointer.
4497 4486 * mr: pointer for mailbox data.
4498 4487 *
4499 4488 * Returns:
4500 4489 * ql local function return status code.
4501 4490 *
4502 4491 * Context:
4503 4492 * Kernel context.
4504 4493 */
4505 4494 int
4506 4495 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4507 4496 {
4508 4497 int rval;
4509 4498 mbx_cmd_t mc = {0};
4510 4499 mbx_cmd_t *mcp = &mc;
4511 4500
4512 4501 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4513 4502
4514 4503 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4515 4504 mcp->out_mb = MBX_0;
4516 4505 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4517 4506 mcp->timeout = MAILBOX_TOV;
4518 4507 rval = ql_mailbox_command(ha, mcp);
4519 4508
4520 4509 if (rval == QL_SUCCESS) {
4521 4510 if (mrp != NULL) {
4522 4511 mrp->mb[1] = mcp->mb[1];
4523 4512 mrp->mb[2] = mcp->mb[2];
4524 4513 mrp->mb[3] = mcp->mb[3];
4525 4514 mrp->mb[4] = mcp->mb[4];
4526 4515 }
4527 4516 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4528 4517 } else {
4529 4518 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n",
4530 4519 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]);
4531 4520 }
4532 4521
4533 4522 return (rval);
4534 4523 }
4535 4524
4536 4525 /*
4537 4526 * ql_flash_access
4538 4527 * The Get Port Configuration command retrieves the current configuration
4539 4528 * for the external 10G port associated with this function
4540 4529 *
4541 4530 * Input:
4542 4531 * ha: adapter state pointer.
4543 4532 * cmd: command.
4544 4533 * start: 32bit word address.
4545 4534 * end: 32bit word address.
4546 4535 * dp: 32bit word pointer.
4547 4536 *
4548 4537 * Returns:
4549 4538 * ql local function return status code.
4550 4539 *
4551 4540 * Context:
4552 4541 * Kernel context.
4553 4542 */
4554 4543 int
4555 4544 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start,
4556 4545 uint32_t end, uint32_t *dp)
4557 4546 {
4558 4547 int rval;
4559 4548 mbx_cmd_t mc = {0};
4560 4549 mbx_cmd_t *mcp = &mc;
4561 4550
4562 4551 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4563 4552
4564 4553 mcp->mb[0] = MBC_FLASH_ACCESS;
4565 4554 if (cmd > 0 && cmd < 4) {
4566 4555 mcp->mb[1] = (uint16_t)(FAC_FORCE_SEMA_LOCK | cmd);
4567 4556 } else {
4568 4557 mcp->mb[1] = cmd;
4569 4558 }
4570 4559 mcp->mb[2] = LSW(start);
4571 4560 mcp->mb[3] = MSW(start);
4572 4561 mcp->mb[4] = LSW(end);
4573 4562 mcp->mb[5] = MSW(end);
4574 4563
4575 4564 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4576 4565 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4577 4566 mcp->timeout = MAILBOX_TOV;
4578 4567 rval = ql_mailbox_command(ha, mcp);
4579 4568
4580 4569 if (rval != QL_SUCCESS) {
4581 4570 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4582 4571 mcp->mb[2]);
4583 4572 } else {
4584 4573 if (dp != NULL) {
4585 4574 *dp = (uint32_t)mcp->mb[1];
4586 4575 }
4587 4576 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4588 4577 }
4589 4578
4590 4579 return (rval);
4591 4580 }
4592 4581
4593 4582 /*
4594 4583 * ql_get_xgmac_stats
4595 4584 * Issue et XGMAC Statistics Mailbox command
4596 4585 *
4597 4586 * Input:
4598 4587 * ha: adapter state pointer.
4599 4588 * size: size of data buffer.
4600 4589 * bufp: data pointer for DMA data.
4601 4590 *
4602 4591 * Returns:
4603 4592 * ql local function return status code.
4604 4593 *
4605 4594 * Context:
4606 4595 * Kernel context.
4607 4596 */
4608 4597 int
4609 4598 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
4610 4599 {
4611 4600 int rval;
4612 4601 dma_mem_t mem_desc;
4613 4602 mbx_cmd_t mc = {0};
4614 4603 mbx_cmd_t *mcp = &mc;
4615 4604
4616 4605 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4617 4606
4618 4607 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4619 4608 (uint32_t)size)) != QL_SUCCESS) {
4620 4609 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
4621 4610 return (QL_MEMORY_ALLOC_FAILED);
4622 4611 }
4623 4612
4624 4613 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4625 4614 mcp->mb[2] = MSW(mem_desc.cookie.dmac_address);
4626 4615 mcp->mb[3] = LSW(mem_desc.cookie.dmac_address);
4627 4616 mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused);
4628 4617 mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused);
4629 4618 mcp->mb[8] = (uint16_t)(size >> 2);
4630 4619 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4631 4620 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4632 4621 mcp->timeout = MAILBOX_TOV;
4633 4622 rval = ql_mailbox_command(ha, mcp);
4634 4623
4635 4624 if (rval == QL_SUCCESS) {
4636 4625 ql_get_mbox_dma_data(&mem_desc, bufp);
4637 4626 }
4638 4627 ql_free_dma_resource(ha, &mem_desc);
4639 4628
4640 4629 if (rval != QL_SUCCESS) {
4641 4630 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4642 4631 mcp->mb[2]);
4643 4632 } else {
4644 4633 /*EMPTY*/
4645 4634 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4646 4635 }
4647 4636
4648 4637 return (rval);
4649 4638 }
4650 4639
4651 4640 /*
4652 4641 * ql_get_dcbx_params
4653 4642 * Issue get DCBX parameters mailbox command.
4654 4643 *
4655 4644 * Input:
4656 4645 * ha: adapter state pointer.
4657 4646 * size: size of data buffer.
4658 4647 * bufp: data pointer for DMA data.
4659 4648 *
4660 4649 * Returns:
4661 4650 * ql local function return status code.
4662 4651 *
4663 4652 * Context:
4664 4653 * Kernel context.
4665 4654 */
4666 4655 int
4667 4656 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp)
4668 4657 {
4669 4658 int rval;
4670 4659 dma_mem_t mem_desc;
4671 4660 mbx_cmd_t mc = {0};
4672 4661 mbx_cmd_t *mcp = &mc;
4673 4662
4674 4663 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4675 4664
4676 4665 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) !=
4677 4666 QL_SUCCESS) {
4678 4667 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4679 4668 return (QL_MEMORY_ALLOC_FAILED);
4680 4669 }
4681 4670
4682 4671 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4683 4672 mcp->mb[1] = 0; /* Return all DCBX paramters */
4684 4673 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4685 4674 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4686 4675 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4687 4676 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4688 4677 mcp->mb[8] = (uint16_t)size;
4689 4678 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4690 4679 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4691 4680 mcp->timeout = MAILBOX_TOV;
4692 4681 rval = ql_mailbox_command(ha, mcp);
4693 4682
4694 4683 if (rval == QL_SUCCESS) {
4695 4684 ql_get_mbox_dma_data(&mem_desc, bufp);
4696 4685 }
4697 4686
4698 4687 ql_free_dma_resource(ha, &mem_desc);
4699 4688
4700 4689 if (rval != QL_SUCCESS) {
4701 4690 EL(ha, "failed=%xh\n", rval);
4702 4691 } else {
4703 4692 /*EMPTY*/
4704 4693 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4705 4694 }
4706 4695
4707 4696 return (rval);
4708 4697 }
4709 4698 /*
4710 4699 * ql_get_fcf_list
4711 4700 * Issue get FCF list mailbox command.
4712 4701 *
4713 4702 * Input:
4714 4703 * ha: adapter state pointer.
4715 4704 * fcf_list: pointer to ql_fcf_list_desc_t
4716 4705 * bufp: data pointer for DMA data.
4717 4706 *
4718 4707 * Returns:
4719 4708 * ql local function return status code.
4720 4709 *
4721 4710 * Context:
4722 4711 * Kernel context.
4723 4712 */
4724 4713
4725 4714 int
4726 4715 ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list,
4727 4716 caddr_t bufp)
4728 4717 {
4729 4718 int rval;
4730 4719 dma_mem_t mem_desc;
4731 4720 mbx_cmd_t mc = {0};
4732 4721 mbx_cmd_t *mcp = &mc;
4733 4722
4734 4723 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4735 4724
4736 4725 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4737 4726 fcf_list->buffer_size)) !=
4738 4727 QL_SUCCESS) {
4739 4728 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4740 4729 return (QL_MEMORY_ALLOC_FAILED);
4741 4730 }
4742 4731
4743 4732 mcp->mb[0] = MBC_GET_FCF_LIST;
4744 4733 mcp->mb[1] = fcf_list->options;
4745 4734 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4746 4735 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4747 4736 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4748 4737 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4749 4738 mcp->mb[8] = (uint16_t)fcf_list->buffer_size;
4750 4739 mcp->mb[9] = fcf_list->fcf_index;
4751 4740 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4752 4741 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4753 4742 mcp->timeout = MAILBOX_TOV;
4754 4743 rval = ql_mailbox_command(ha, mcp);
4755 4744
4756 4745 if (rval == QL_SUCCESS) {
4757 4746 ql_get_mbox_dma_data(&mem_desc, bufp);
4758 4747 fcf_list->buffer_size = (uint16_t)mcp->mb[1];
4759 4748 }
4760 4749
4761 4750 ql_free_dma_resource(ha, &mem_desc);
4762 4751
4763 4752 if (rval != QL_SUCCESS) {
4764 4753 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4765 4754 mcp->mb[2]);
4766 4755 } else {
4767 4756 /*EMPTY*/
4768 4757 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4769 4758 }
4770 4759
4771 4760 return (rval);
4772 4761 }
4773 4762
4774 4763 /*
4775 4764 * ql_get_resource_cnts
4776 4765 * Issue get Resourse Count mailbox command.
4777 4766 *
4778 4767 * Input:
4779 4768 * ha: adapter state pointer.
4780 4769 * mr: pointer for mailbox data.
4781 4770 *
4782 4771 * Returns:
4783 4772 * ql local function return status code.
4784 4773 *
4785 4774 * Context:
4786 4775 * Kernel context.
4787 4776 */
4788 4777
4789 4778 int
4790 4779 ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4791 4780 {
4792 4781 int rval;
4793 4782 mbx_cmd_t mc = {0};
4794 4783 mbx_cmd_t *mcp = &mc;
4795 4784
4796 4785 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4797 4786
4798 4787 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
4799 4788 mcp->out_mb = MBX_0;
4800 4789 mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
4801 4790 MBX_3|MBX_2|MBX_1|MBX_0;
4802 4791 mcp->timeout = MAILBOX_TOV;
4803 4792 rval = ql_mailbox_command(ha, mcp);
4804 4793
4805 4794 /* Return mailbox data. */
4806 4795 if (mr != NULL) {
4807 4796 mr->mb[1] = mcp->mb[1];
4808 4797 mr->mb[2] = mcp->mb[2];
4809 4798 mr->mb[3] = mcp->mb[3];
4810 4799 mr->mb[6] = mcp->mb[6];
4811 4800 mr->mb[7] = mcp->mb[7];
4812 4801 mr->mb[10] = mcp->mb[10];
4813 4802 mr->mb[11] = mcp->mb[11];
4814 4803 mr->mb[12] = mcp->mb[12];
4815 4804 }
4816 4805
4817 4806 if (rval != QL_SUCCESS) {
4818 4807 EL(ha, "failed=%xh\n", rval);
4819 4808 } else {
4820 4809 /*EMPTY*/
4821 4810 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4822 4811 }
4823 4812
4824 4813 return (rval);
4825 4814 }
4826 4815
4827 4816 /*
4828 4817 * ql_toggle_interrupt
4829 4818 * Issue Toggle Interrupt Mailbox Command.
4830 4819 *
4831 4820 * Input:
4832 4821 * ha: adapter state pointer.
4833 4822 * opt: 0 = disable, 1 = enable.
4834 4823 *
4835 4824 * Returns:
4836 4825 * ql local function return status code.
4837 4826 *
4838 4827 * Context:
4839 4828 * Kernel context.
4840 4829 */
4841 4830 int
4842 4831 ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt)
4843 4832 {
4844 4833 int rval;
4845 4834 mbx_cmd_t mc = {0};
4846 4835 mbx_cmd_t *mcp = &mc;
4847 4836
4848 4837 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4849 4838
4850 4839 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
4851 4840 mcp->mb[1] = opt;
4852 4841 mcp->out_mb = MBX_1|MBX_0;
4853 4842 mcp->in_mb = MBX_0;
4854 4843 mcp->timeout = 2;
4855 4844 rval = ql_mailbox_command(ha, mcp);
4856 4845
4857 4846 if (rval != QL_SUCCESS) {
4858 4847 EL(ha, "failed=%xh\n", rval);
4859 4848 } else {
4860 4849 /*EMPTY*/
4861 4850 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4862 4851 }
4863 4852
4864 4853 return (rval);
4865 4854 }
↓ open down ↓ |
2154 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX