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