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 2008 QLogic Corporation */ 23 24 /* 25 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #pragma ident "Copyright 2008 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-2008 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 95 ASSERT(!MUTEX_HELD(&ha->mutex)); 96 97 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 98 99 /* Acquire mailbox register lock. */ 100 MBX_REGISTER_LOCK(ha); 101 102 /* Check for mailbox available, if not wait for signal. */ 103 while (ha->mailbox_flags & MBX_BUSY_FLG) { 104 ha->mailbox_flags = (uint8_t) 105 (ha->mailbox_flags | MBX_WANT_FLG); 106 107 if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) { 108 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]); 109 MBX_REGISTER_UNLOCK(ha); 110 return (QL_LOCK_TIMEOUT); 111 } 112 113 /* Set timeout after command that is running. */ 114 timer = ddi_get_lbolt(); 115 timer += (mcp->timeout + 20) * drv_usectohz(1000000); 116 cv_stat = cv_timedwait_sig(&ha->cv_mbx_wait, 117 &ha->mbx_mutex, timer); 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[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 CFG_IST(ha, CFG_CTRL_2425) ? 158 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) : 159 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT); 160 161 /* Wait for command to complete. */ 162 if (ha->flags & INTERRUPTS_ENABLED && 163 !(ha->task_daemon_flags & (TASK_THREAD_CALLED | 164 TASK_DAEMON_POWERING_DOWN)) && 165 !ddi_in_panic()) { 166 while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) && 167 !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) { 168 169 /* 30 seconds from now */ 170 timer = ddi_get_lbolt(); 171 timer += mcp->timeout * drv_usectohz(1000000); 172 if (cv_timedwait(&ha->cv_mbx_intr, &ha->mbx_mutex, 173 timer) == -1) { 174 /* 175 * The timeout time 'timer' was 176 * reached without the condition 177 * being signaled. 178 */ 179 break; 180 } 181 } 182 } else { 183 /* Release mailbox register lock. */ 184 MBX_REGISTER_UNLOCK(ha); 185 186 /* Acquire interrupt lock. */ 187 for (timer = mcp->timeout * 100; timer; timer--) { 188 /* Check for pending interrupts. */ 189 while (RD16_IO_REG(ha, istatus) & RISC_INT) { 190 (void) ql_isr((caddr_t)ha); 191 INTR_LOCK(ha); 192 ha->intr_claimed = B_TRUE; 193 INTR_UNLOCK(ha); 194 if (ha->mailbox_flags & 195 (MBX_INTERRUPT | MBX_ABORT) || 196 ha->task_daemon_flags & ISP_ABORT_NEEDED) { 197 break; 198 } 199 } 200 if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) || 201 ha->task_daemon_flags & ISP_ABORT_NEEDED) { 202 break; 203 } else if (!ddi_in_panic() && timer % 101 == 0) { 204 delay(drv_usectohz(10000)); 205 } else { 206 drv_usecwait(10000); 207 } 208 } 209 210 /* Acquire mailbox register lock. */ 211 MBX_REGISTER_LOCK(ha); 212 } 213 214 /* Mailbox command timeout? */ 215 if (ha->task_daemon_flags & ISP_ABORT_NEEDED || 216 ha->mailbox_flags & MBX_ABORT) { 217 rval = QL_ABORTED; 218 } else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) { 219 if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) { 220 (void) ql_binary_fw_dump(ha, FALSE); 221 } 222 EL(vha, "command timeout, isp_abort_needed\n"); 223 set_flags |= ISP_ABORT_NEEDED; 224 rval = QL_FUNCTION_TIMEOUT; 225 } else { 226 ha->mailbox_flags = (uint8_t) 227 (ha->mailbox_flags & ~MBX_INTERRUPT); 228 229 rval = mcp->mb[0]; 230 } 231 232 /* reset outbound to risc mailbox registers. */ 233 data = (mcp->out_mb >> 1); 234 for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) { 235 if (data & MBX_0) { 236 WRT16_IO_REG(ha, mailbox[cnt], (uint16_t)0); 237 } 238 data >>= 1; 239 } 240 241 /* Reset busy status. */ 242 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 243 ~(MBX_BUSY_FLG | MBX_ABORT)); 244 ha->mcp = NULL; 245 246 /* If thread is waiting for mailbox go signal it to start. */ 247 if (ha->mailbox_flags & MBX_WANT_FLG) { 248 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 249 ~MBX_WANT_FLG); 250 cv_broadcast(&ha->cv_mbx_wait); 251 } 252 253 /* Release mailbox register lock. */ 254 MBX_REGISTER_UNLOCK(ha); 255 256 if (set_flags != 0 || reset_flags != 0) { 257 ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags); 258 } 259 260 if (rval != QL_SUCCESS) { 261 EL(vha, "failed, rval=%xh, mcp->mb[0]=%xh\n", rval, 262 mcp->mb[0]); 263 } else { 264 /*EMPTY*/ 265 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 266 } 267 268 return (rval); 269 } 270 271 /* 272 * ql_setup_mbox_dma_resources 273 * Prepare the data for a mailbox dma transfer. 274 * 275 * Input: 276 * ha = adapter state pointer. 277 * mem_desc = descriptor to contain the dma resource information. 278 * data = pointer to the data. 279 * size = size of the data in bytes. 280 * 281 * Returns: 282 * ql local function return status code. 283 * 284 * Context: 285 * Kernel context. 286 */ 287 static int 288 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc, 289 caddr_t data, uint32_t size) 290 { 291 int rval = QL_SUCCESS; 292 293 if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) == 294 QL_SUCCESS) { 295 ql_setup_mbox_dma_data(mem_desc, data); 296 } else { 297 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 298 } 299 300 return (rval); 301 } 302 303 /* 304 * ql_setup_mbox_dma_resources 305 * Prepare a dma buffer. 306 * 307 * Input: 308 * ha = adapter state pointer. 309 * mem_desc = descriptor to contain the dma resource information. 310 * data = pointer to the data. 311 * size = size of the data in bytes. 312 * 313 * Returns: 314 * ql local function return status code. 315 * 316 * Context: 317 * Kernel context. 318 */ 319 static int 320 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc, 321 uint32_t size) 322 { 323 int rval = QL_SUCCESS; 324 325 if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA, 326 MEM_RING_ALIGN)) != QL_SUCCESS) { 327 EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n"); 328 rval = QL_MEMORY_ALLOC_FAILED; 329 } 330 331 return (rval); 332 } 333 334 /* 335 * ql_setup_mbox_dma_data 336 * Move data to the dma buffer. 337 * 338 * Input: 339 * mem_desc = descriptor to contain the dma resource information. 340 * data = pointer to the data. 341 * 342 * Returns: 343 * 344 * Context: 345 * Kernel context. 346 */ 347 static void 348 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data) 349 { 350 /* Copy out going data to DMA buffer. */ 351 ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data, 352 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR); 353 354 /* Sync DMA buffer. */ 355 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size, 356 DDI_DMA_SYNC_FORDEV); 357 } 358 359 /* 360 * ql_get_mbox_dma_data 361 * Recover data from the dma buffer. 362 * 363 * Input: 364 * mem_desc = descriptor to contain the dma resource information. 365 * data = pointer to the data. 366 * 367 * Returns: 368 * 369 * Context: 370 * Kernel context. 371 */ 372 static void 373 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data) 374 { 375 /* Sync in coming DMA buffer. */ 376 (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size, 377 DDI_DMA_SYNC_FORKERNEL); 378 /* Copy in coming DMA data. */ 379 ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data, 380 (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR); 381 } 382 383 /* 384 * ql_initialize_ip 385 * Initialize IP receive buffer queue. 386 * 387 * Input: 388 * ha = adapter state pointer. 389 * ha->ip_init_ctrl_blk = setup for transmit. 390 * 391 * Returns: 392 * ql local function return status code. 393 * 394 * Context: 395 * Kernel context. 396 */ 397 int 398 ql_initialize_ip(ql_adapter_state_t *ha) 399 { 400 ql_link_t *link; 401 ql_tgt_t *tq; 402 uint16_t index; 403 int rval; 404 dma_mem_t mem_desc; 405 mbx_cmd_t mc = {0}; 406 mbx_cmd_t *mcp = &mc; 407 408 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 409 410 if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_25XX)) || 411 ha->vp_index != 0) { 412 ha->flags &= ~IP_INITIALIZED; 413 EL(ha, "HBA does not support IP\n"); 414 return (QL_FUNCTION_FAILED); 415 } 416 417 ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp; 418 ha->rcvbuf_ring_index = 0; 419 420 /* Reset all sequence counts. */ 421 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 422 for (link = ha->dev[index].first; link != NULL; 423 link = link->next) { 424 tq = link->base_address; 425 tq->ub_total_seg_cnt = 0; 426 } 427 } 428 429 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 430 (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t)); 431 if (rval != QL_SUCCESS) { 432 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 433 return (rval); 434 } 435 436 mcp->mb[0] = MBC_INITIALIZE_IP; 437 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 438 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 439 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 440 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 441 mcp->mb[8] = 0; 442 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 443 mcp->in_mb = MBX_8|MBX_0; 444 mcp->timeout = MAILBOX_TOV; 445 rval = ql_mailbox_command(ha, mcp); 446 447 ql_free_dma_resource(ha, &mem_desc); 448 449 if (rval == QL_SUCCESS) { 450 ADAPTER_STATE_LOCK(ha); 451 ha->flags |= IP_INITIALIZED; 452 ADAPTER_STATE_UNLOCK(ha); 453 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 454 } else { 455 ha->flags &= ~IP_INITIALIZED; 456 EL(ha, "failed, rval = %xh\n", rval); 457 } 458 return (rval); 459 } 460 461 /* 462 * ql_shutdown_ip 463 * Disconnects firmware IP from system buffers. 464 * 465 * Input: 466 * ha = adapter state pointer. 467 * 468 * Returns: 469 * ql local function return status code. 470 * 471 * Context: 472 * Kernel context. 473 */ 474 int 475 ql_shutdown_ip(ql_adapter_state_t *ha) 476 { 477 int rval; 478 mbx_cmd_t mc = {0}; 479 mbx_cmd_t *mcp = &mc; 480 fc_unsol_buf_t *ubp; 481 ql_srb_t *sp; 482 uint16_t index; 483 484 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 485 486 mcp->mb[0] = MBC_UNLOAD_IP; 487 mcp->out_mb = MBX_0; 488 mcp->in_mb = MBX_0; 489 mcp->timeout = MAILBOX_TOV; 490 rval = ql_mailbox_command(ha, mcp); 491 492 ADAPTER_STATE_LOCK(ha); 493 QL_UB_LOCK(ha); 494 /* Return all unsolicited buffers that ISP-IP has. */ 495 for (index = 0; index < QL_UB_LIMIT; index++) { 496 ubp = ha->ub_array[index]; 497 if (ubp != NULL) { 498 sp = ubp->ub_fca_private; 499 sp->flags &= ~SRB_UB_IN_ISP; 500 } 501 } 502 503 ha->ub_outcnt = 0; 504 QL_UB_UNLOCK(ha); 505 ha->flags &= ~IP_INITIALIZED; 506 ADAPTER_STATE_UNLOCK(ha); 507 508 if (rval == QL_SUCCESS) { 509 /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */ 510 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 511 } else { 512 EL(ha, "failed, rval = %xh\n", rval); 513 } 514 return (rval); 515 } 516 517 /* 518 * ql_online_selftest 519 * Issue online self test mailbox command. 520 * 521 * Input: 522 * ha = adapter state pointer. 523 * 524 * Returns: 525 * ql local function return status code. 526 * 527 * Context: 528 * Kernel context. 529 */ 530 int 531 ql_online_selftest(ql_adapter_state_t *ha) 532 { 533 int rval; 534 mbx_cmd_t mc = {0}; 535 mbx_cmd_t *mcp = &mc; 536 537 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 538 539 mcp->mb[0] = MBC_ONLINE_SELF_TEST; 540 mcp->out_mb = MBX_0; 541 mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3; 542 mcp->timeout = MAILBOX_TOV; 543 rval = ql_mailbox_command(ha, mcp); 544 545 if (rval != QL_SUCCESS) { 546 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n", 547 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]); 548 } else { 549 /*EMPTY*/ 550 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 551 } 552 return (rval); 553 } 554 555 /* 556 * ql_loop_back 557 * Issue diagnostic loop back frame mailbox command. 558 * 559 * Input: 560 * ha = adapter state pointer. 561 * lb = loop back parameter structure pointer. 562 * 563 * Returns: 564 * ql local function return status code. 565 * 566 * Context: 567 * Kernel context. 568 */ 569 #ifndef apps_64bit 570 int 571 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb, uint32_t h_xmit, 572 uint32_t h_rcv) 573 { 574 int rval; 575 mbx_cmd_t mc = {0}; 576 mbx_cmd_t *mcp = &mc; 577 578 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 579 580 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 581 mcp->mb[1] = lb->options; 582 mcp->mb[6] = LSW(h_rcv); 583 mcp->mb[7] = MSW(h_rcv); 584 mcp->mb[10] = LSW(lb->transfer_count); 585 mcp->mb[11] = MSW(lb->transfer_count); 586 mcp->mb[12] = lb->transfer_segment_count; 587 mcp->mb[13] = lb->receive_segment_count; 588 mcp->mb[14] = LSW(lb->transfer_data_address); 589 mcp->mb[15] = MSW(lb->transfer_data_address); 590 mcp->mb[16] = LSW(lb->receive_data_address); 591 mcp->mb[17] = MSW(lb->receive_data_address); 592 mcp->mb[18] = LSW(lb->iteration_count); 593 mcp->mb[19] = MSW(lb->iteration_count); 594 mcp->mb[20] = LSW(h_xmit); 595 mcp->mb[21] = MSW(h_xmit); 596 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 597 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 598 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 599 mcp->timeout = lb->iteration_count / 300; 600 601 if (mcp->timeout < MAILBOX_TOV) { 602 mcp->timeout = MAILBOX_TOV; 603 } 604 605 rval = ql_mailbox_command(ha, mcp); 606 607 if (rval != QL_SUCCESS) { 608 EL(ha, "failed, rval = %xh\n", rval); 609 } else { 610 /*EMPTY*/ 611 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 612 } 613 614 return (rval); 615 } 616 #else 617 int 618 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb) 619 { 620 int rval; 621 mbx_cmd_t mc = {0}; 622 mbx_cmd_t *mcp = &mc; 623 624 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 625 626 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 627 mcp->mb[1] = lb->options; 628 mcp->mb[6] = LSW(h_rcv); 629 mcp->mb[7] = MSW(h_rcv); 630 mcp->mb[6] = LSW(MSD(lb->receive_data_address)); 631 mcp->mb[7] = MSW(MSD(lb->receive_data_address)); 632 mcp->mb[10] = LSW(lb->transfer_count); 633 mcp->mb[11] = MSW(lb->transfer_count); 634 mcp->mb[12] = lb->transfer_segment_count; 635 mcp->mb[13] = lb->receive_segment_count; 636 mcp->mb[14] = LSW(lb->transfer_data_address); 637 mcp->mb[15] = MSW(lb->transfer_data_address); 638 mcp->mb[14] = LSW(LSD(lb->transfer_data_address)); 639 mcp->mb[15] = MSW(LSD(lb->transfer_data_address)); 640 mcp->mb[16] = LSW(lb->receive_data_address); 641 mcp->mb[17] = MSW(lb->receive_data_address); 642 mcp->mb[16] = LSW(LSD(lb->receive_data_address)); 643 mcp->mb[17] = MSW(LSD(lb->receive_data_address)); 644 mcp->mb[18] = LSW(lb->iteration_count); 645 mcp->mb[19] = MSW(lb->iteration_count); 646 mcp->mb[20] = LSW(h_xmit); 647 mcp->mb[21] = MSW(h_xmit); 648 mcp->mb[20] = LSW(MSD(lb->transfer_data_address)); 649 mcp->mb[21] = MSW(MSD(lb->transfer_data_address)); 650 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 651 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 652 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 653 mcp->timeout = lb->iteration_count / 300; 654 655 if (mcp->timeout < MAILBOX_TOV) { 656 mcp->timeout = MAILBOX_TOV; 657 } 658 659 rval = ql_mailbox_command(ha, mcp); 660 661 if (rval != QL_SUCCESS) { 662 EL(ha, "failed, rval = %xh\n", rval); 663 } else { 664 /*EMPTY*/ 665 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 666 } 667 return (rval); 668 } 669 #endif 670 671 /* 672 * ql_echo 673 * Issue an ELS echo using the user specified data to a user specified 674 * destination 675 * 676 * Input: 677 * ha: adapter state pointer. 678 * echo_pt: echo parameter structure pointer. 679 * 680 * Returns: 681 * ql local function return status code. 682 * 683 * Context: 684 * Kernel context. 685 */ 686 int 687 ql_echo(ql_adapter_state_t *ha, echo_t *echo_pt) 688 { 689 int rval; 690 mbx_cmd_t mc = {0}; 691 mbx_cmd_t *mcp = &mc; 692 693 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 694 695 mcp->mb[0] = MBC_ECHO; /* ECHO command */ 696 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */ 697 /* addressing (bit 6) and */ 698 /* real echo (bit 15 */ 699 700 /* 701 * I know this looks strange, using a field labled "not used" 702 * The way the ddi_dma_cookie_t structure/union is defined 703 * is a union of one 64 bit entity with an array of two 32 704 * bit enititys. Since we have routines to convert 32 bit 705 * entities into 16 bit entities it is easier to use 706 * both 32 bit union members then the one 64 bit union 707 * member 708 */ 709 if (echo_pt->options & BIT_6) { 710 /* 64 bit addressing */ 711 /* Receive data dest add in system memory bits 47-32 */ 712 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused); 713 714 /* Receive data dest add in system memory bits 63-48 */ 715 mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused); 716 717 /* Transmit data source address in system memory bits 47-32 */ 718 mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused); 719 720 /* Transmit data source address in system memory bits 63-48 */ 721 mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused); 722 } else { 723 mcp->mb[6] = 0; /* bits 63-48 */ 724 mcp->mb[7] = 0; /* bits 47-32 */ 725 mcp->mb[20] = 0; /* bits 63-48 */ 726 mcp->mb[21] = 0; /* bits 47-32 */ 727 } 728 729 /* transfer count bits 15-0 */ 730 mcp->mb[10] = LSW(echo_pt->transfer_count); 731 732 /* Transmit data source address in system memory bits 15-0 */ 733 mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address); 734 735 /* Transmit data source address in system memory bits 31-16 */ 736 mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address); 737 738 /* Receive data destination address in system memory bits 15-0 */ 739 mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address); 740 741 /* Receive data destination address in system memory bits 31-16 */ 742 mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address); 743 744 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10| 745 MBX_7|MBX_6|MBX_1|MBX_0; 746 mcp->in_mb = MBX_1|MBX_0; 747 mcp->timeout = MAILBOX_TOV; 748 749 rval = ql_mailbox_command(ha, mcp); 750 751 if (rval != QL_SUCCESS) { 752 EL(ha, "failed, rval = %xh\n", rval); 753 } else { 754 /*EMPTY*/ 755 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 756 } 757 return (rval); 758 } 759 760 /* 761 * ql_send_change_request 762 * Issue send change request mailbox command. 763 * 764 * Input: 765 * ha: adapter state pointer. 766 * fmt: Registration format. 767 * 768 * Returns: 769 * ql local function return status code. 770 * 771 * Context: 772 * Kernel context. 773 */ 774 int 775 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt) 776 { 777 int rval; 778 mbx_cmd_t mc = {0}; 779 mbx_cmd_t *mcp = &mc; 780 781 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 782 783 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 784 mcp->mb[1] = fmt; 785 mcp->out_mb = MBX_1|MBX_0; 786 if (ha->flags & VP_ENABLED) { 787 mcp->mb[9] = ha->vp_index; 788 mcp->out_mb |= MBX_9; 789 } 790 mcp->in_mb = MBX_0; 791 mcp->timeout = MAILBOX_TOV; 792 rval = ql_mailbox_command(ha, mcp); 793 794 if (rval != QL_SUCCESS) { 795 EL(ha, "failed=%xh\n", rval); 796 } else { 797 /*EMPTY*/ 798 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 799 } 800 return (rval); 801 } 802 803 /* 804 * ql_send_lfa 805 * Send a Loop Fabric Address mailbox command. 806 * 807 * Input: 808 * ha: adapter state pointer. 809 * lfa: LFA command structure pointer. 810 * 811 * Returns: 812 * ql local function return status code. 813 * 814 * Context: 815 * Kernel context. 816 */ 817 int 818 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa) 819 { 820 int rval; 821 uint16_t size; 822 dma_mem_t mem_desc; 823 mbx_cmd_t mc = {0}; 824 mbx_cmd_t *mcp = &mc; 825 826 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 827 828 /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */ 829 size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1); 830 831 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size); 832 if (rval != QL_SUCCESS) { 833 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 834 return (rval); 835 } 836 837 mcp->mb[0] = MBC_SEND_LFA_COMMAND; 838 mcp->mb[1] = (uint16_t)(size >> 1); 839 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 840 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 841 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 842 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 843 mcp->in_mb = MBX_0; 844 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 845 if (ha->flags & VP_ENABLED) { 846 mcp->mb[9] = ha->vp_index; 847 mcp->out_mb |= MBX_9; 848 } 849 mcp->timeout = MAILBOX_TOV; 850 rval = ql_mailbox_command(ha, mcp); 851 852 ql_free_dma_resource(ha, &mem_desc); 853 854 if (rval != QL_SUCCESS) { 855 EL(ha, "failed, rval = %xh\n", rval); 856 } else { 857 /*EMPTY*/ 858 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 859 } 860 861 return (rval); 862 } 863 864 /* 865 * ql_clear_aca 866 * Issue clear ACA mailbox command. 867 * 868 * Input: 869 * ha: adapter state pointer. 870 * tq: target queue pointer. 871 * lun: LUN. 872 * 873 * Returns: 874 * ql local function return status code. 875 * 876 * Context: 877 * Kernel context. 878 */ 879 int 880 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 881 { 882 int rval; 883 mbx_cmd_t mc = {0}; 884 mbx_cmd_t *mcp = &mc; 885 886 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 887 888 if (CFG_IST(ha, CFG_CTRL_2425)) { 889 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0); 890 } else { 891 mcp->mb[0] = MBC_CLEAR_ACA; 892 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 893 mcp->mb[1] = tq->loop_id; 894 } else { 895 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 896 } 897 mcp->mb[2] = lun; 898 mcp->out_mb = MBX_2|MBX_1|MBX_0; 899 mcp->in_mb = MBX_0; 900 mcp->timeout = MAILBOX_TOV; 901 rval = ql_mailbox_command(ha, mcp); 902 } 903 904 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 905 906 if (rval != QL_SUCCESS) { 907 EL(ha, "failed, rval = %xh\n", rval); 908 } else { 909 /*EMPTY*/ 910 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 911 } 912 913 return (rval); 914 } 915 916 /* 917 * ql_target_reset 918 * Issue target reset mailbox command. 919 * 920 * Input: 921 * ha: adapter state pointer. 922 * tq: target queue pointer. 923 * delay: seconds. 924 * 925 * Returns: 926 * ql local function return status code. 927 * 928 * Context: 929 * Kernel context. 930 */ 931 int 932 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay) 933 { 934 ql_link_t *link; 935 uint16_t index; 936 int rval; 937 mbx_cmd_t mc = {0}; 938 mbx_cmd_t *mcp = &mc; 939 940 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 941 942 if (CFG_IST(ha, CFG_CTRL_2425)) { 943 /* queue = NULL, all targets. */ 944 if (tq == NULL) { 945 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; 946 index++) { 947 for (link = ha->dev[index].first; link != 948 NULL; link = link->next) { 949 tq = link->base_address; 950 if (!VALID_DEVICE_ID(ha, 951 tq->loop_id)) { 952 continue; 953 } 954 rval = ql_task_mgmt_iocb(ha, tq, 0, 955 CF_TARGET_RESET, delay); 956 957 if (rval != QL_SUCCESS) { 958 break; 959 } 960 } 961 962 if (link != NULL) { 963 break; 964 } 965 } 966 tq = NULL; 967 } else { 968 rval = ql_task_mgmt_iocb(ha, tq, 0, CF_TARGET_RESET, 969 delay); 970 } 971 } else { 972 /* queue = NULL, all targets. */ 973 if (tq == NULL) { 974 mcp->mb[0] = MBC_RESET; 975 mcp->mb[1] = delay; 976 mcp->out_mb = MBX_1|MBX_0; 977 } else { 978 mcp->mb[0] = MBC_TARGET_RESET; 979 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 980 mcp->mb[1] = tq->loop_id; 981 } else { 982 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 983 } 984 mcp->mb[2] = delay; 985 mcp->out_mb = MBX_2|MBX_1|MBX_0; 986 } 987 mcp->in_mb = MBX_0; 988 mcp->timeout = MAILBOX_TOV; 989 rval = ql_mailbox_command(ha, mcp); 990 } 991 992 tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) : 993 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 994 995 if (rval != QL_SUCCESS) { 996 EL(ha, "failed, rval = %xh\n", rval); 997 } else { 998 /*EMPTY*/ 999 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1000 } 1001 1002 return (rval); 1003 } 1004 1005 /* 1006 * ql_abort_target 1007 * Issue abort target mailbox command. 1008 * 1009 * Input: 1010 * ha: adapter state pointer. 1011 * tq: target queue pointer. 1012 * delay: in seconds. 1013 * 1014 * Returns: 1015 * qla2x00 local function return status code. 1016 * 1017 * Context: 1018 * Kernel context. 1019 */ 1020 int 1021 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay) 1022 { 1023 int rval; 1024 mbx_cmd_t mc = {0}; 1025 mbx_cmd_t *mcp = &mc; 1026 1027 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1028 1029 if (CFG_IST(ha, CFG_CTRL_2425)) { 1030 rval = ql_task_mgmt_iocb(ha, tq, 0, 1031 CF_DO_NOT_SEND | CF_TARGET_RESET, delay); 1032 } else { 1033 mcp->mb[0] = MBC_ABORT_TARGET; 1034 /* Don't send Task Mgt */ 1035 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1036 mcp->mb[1] = tq->loop_id; 1037 mcp->mb[10] = BIT_0; 1038 mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0; 1039 } else { 1040 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0); 1041 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1042 } 1043 mcp->mb[2] = delay; 1044 mcp->in_mb = MBX_0; 1045 mcp->timeout = MAILBOX_TOV; 1046 rval = ql_mailbox_command(ha, mcp); 1047 } 1048 1049 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 1050 1051 if (rval != QL_SUCCESS) { 1052 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1053 } else { 1054 /*EMPTY*/ 1055 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1056 } 1057 return (rval); 1058 } 1059 1060 /* 1061 * ql_lun_reset 1062 * Issue LUN reset task management mailbox command. 1063 * 1064 * Input: 1065 * ha: adapter state pointer. 1066 * tq: target queue pointer. 1067 * lun: LUN. 1068 * 1069 * Returns: 1070 * ql local function return status code. 1071 * 1072 * Context: 1073 * Kernel context. 1074 */ 1075 int 1076 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1077 { 1078 int rval; 1079 mbx_cmd_t mc = {0}; 1080 mbx_cmd_t *mcp = &mc; 1081 1082 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1083 1084 if (CFG_IST(ha, CFG_CTRL_2425)) { 1085 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0); 1086 } else { 1087 mcp->mb[0] = MBC_LUN_RESET; 1088 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1089 mcp->mb[1] = tq->loop_id; 1090 } else { 1091 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1092 } 1093 mcp->mb[2] = lun; 1094 mcp->mb[3] = 0; 1095 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1096 mcp->in_mb = MBX_0; 1097 mcp->timeout = MAILBOX_TOV; 1098 rval = ql_mailbox_command(ha, mcp); 1099 } 1100 1101 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1102 1103 if (rval != QL_SUCCESS) { 1104 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1105 } else { 1106 /*EMPTY*/ 1107 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1108 } 1109 return (rval); 1110 } 1111 1112 /* 1113 * ql_clear_task_set 1114 * Issue clear task set mailbox command. 1115 * 1116 * Input: 1117 * ha: adapter state pointer. 1118 * tq: target queue pointer. 1119 * lun: LUN. 1120 * 1121 * Returns: 1122 * ql local function return status code. 1123 * 1124 * Context: 1125 * Kernel context. 1126 */ 1127 int 1128 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1129 { 1130 int rval; 1131 mbx_cmd_t mc = {0}; 1132 mbx_cmd_t *mcp = &mc; 1133 1134 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1135 1136 if (CFG_IST(ha, CFG_CTRL_2425)) { 1137 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0); 1138 } else { 1139 mcp->mb[0] = MBC_CLEAR_TASK_SET; 1140 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1141 mcp->mb[1] = tq->loop_id; 1142 } else { 1143 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1144 } 1145 mcp->mb[2] = lun; 1146 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1147 mcp->in_mb = MBX_0; 1148 mcp->timeout = MAILBOX_TOV; 1149 rval = ql_mailbox_command(ha, mcp); 1150 } 1151 1152 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1153 1154 if (rval != QL_SUCCESS) { 1155 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1156 } else { 1157 /*EMPTY*/ 1158 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1159 } 1160 1161 return (rval); 1162 } 1163 1164 /* 1165 * ql_abort_task_set 1166 * Issue abort task set mailbox command. 1167 * 1168 * Input: 1169 * ha: adapter state pointer. 1170 * tq: target queue pointer. 1171 * lun: LUN. 1172 * 1173 * Returns: 1174 * ql local function return status code. 1175 * 1176 * Context: 1177 * Kernel context. 1178 */ 1179 int 1180 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1181 { 1182 int rval; 1183 mbx_cmd_t mc = {0}; 1184 mbx_cmd_t *mcp = &mc; 1185 1186 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1187 1188 if (CFG_IST(ha, CFG_CTRL_2425)) { 1189 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0); 1190 } else { 1191 mcp->mb[0] = MBC_ABORT_TASK_SET; 1192 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1193 mcp->mb[1] = tq->loop_id; 1194 } else { 1195 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1196 } 1197 mcp->mb[2] = lun; 1198 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1199 mcp->in_mb = MBX_0; 1200 mcp->timeout = MAILBOX_TOV; 1201 rval = ql_mailbox_command(ha, mcp); 1202 } 1203 1204 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1205 1206 if (rval != QL_SUCCESS) { 1207 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1208 } else { 1209 /*EMPTY*/ 1210 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1211 } 1212 1213 return (rval); 1214 } 1215 1216 /* 1217 * ql_task_mgmt_iocb 1218 * Function issues task management IOCB. 1219 * 1220 * Input: 1221 * ha: adapter state pointer. 1222 * tq: target queue pointer. 1223 * lun: LUN. 1224 * flags: control flags. 1225 * delay: seconds. 1226 * 1227 * Returns: 1228 * ql local function return status code. 1229 * 1230 * Context: 1231 * Kernel context 1232 */ 1233 static int 1234 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun, 1235 uint32_t flags, uint16_t delay) 1236 { 1237 ql_mbx_iocb_t *pkt; 1238 int rval; 1239 uint32_t pkt_size; 1240 1241 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1242 1243 pkt_size = sizeof (ql_mbx_iocb_t); 1244 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1245 if (pkt == NULL) { 1246 EL(ha, "failed, kmem_zalloc\n"); 1247 return (QL_MEMORY_ALLOC_FAILED); 1248 } 1249 1250 pkt->mgmt.entry_type = TASK_MGMT_TYPE; 1251 pkt->mgmt.entry_count = 1; 1252 1253 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 1254 pkt->mgmt.delay = (uint16_t)LE_16(delay); 1255 pkt->mgmt.timeout = LE_16(MAILBOX_TOV); 1256 pkt->mgmt.fcp_lun[2] = LSB(lun); 1257 pkt->mgmt.fcp_lun[3] = MSB(lun); 1258 pkt->mgmt.control_flags = LE_32(flags); 1259 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa; 1260 pkt->mgmt.target_id[1] = tq->d_id.b.area; 1261 pkt->mgmt.target_id[2] = tq->d_id.b.domain; 1262 pkt->mgmt.vp_index = ha->vp_index; 1263 1264 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1265 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) { 1266 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1267 pkt->sts24.entry_status, tq->d_id.b24); 1268 rval = QL_FUNCTION_PARAMETER_ERROR; 1269 } 1270 1271 LITTLE_ENDIAN_16(&pkt->sts24.comp_status); 1272 1273 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) { 1274 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 1275 pkt->sts24.comp_status, tq->d_id.b24); 1276 rval = QL_FUNCTION_FAILED; 1277 } 1278 1279 kmem_free(pkt, pkt_size); 1280 1281 if (rval != QL_SUCCESS) { 1282 EL(ha, "failed, rval = %xh\n", rval); 1283 } else { 1284 /*EMPTY*/ 1285 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1286 } 1287 1288 return (rval); 1289 } 1290 1291 /* 1292 * ql_loop_port_bypass 1293 * Issue loop port bypass mailbox command. 1294 * 1295 * Input: 1296 * ha: adapter state pointer. 1297 * tq: target queue pointer. 1298 * 1299 * Returns: 1300 * ql local function return status code. 1301 * 1302 * Context: 1303 * Kernel context. 1304 */ 1305 int 1306 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq) 1307 { 1308 int rval; 1309 mbx_cmd_t mc = {0}; 1310 mbx_cmd_t *mcp = &mc; 1311 1312 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1313 1314 mcp->mb[0] = MBC_LOOP_PORT_BYPASS; 1315 1316 if (CFG_IST(ha, CFG_CTRL_2425)) { 1317 mcp->mb[1] = tq->d_id.b.al_pa; 1318 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1319 mcp->mb[1] = tq->loop_id; 1320 } else { 1321 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1322 } 1323 1324 mcp->out_mb = MBX_1|MBX_0; 1325 mcp->in_mb = MBX_0; 1326 mcp->timeout = MAILBOX_TOV; 1327 rval = ql_mailbox_command(ha, mcp); 1328 1329 if (rval != QL_SUCCESS) { 1330 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1331 } else { 1332 /*EMPTY*/ 1333 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1334 } 1335 1336 return (rval); 1337 } 1338 1339 /* 1340 * ql_loop_port_enable 1341 * Issue loop port enable mailbox command. 1342 * 1343 * Input: 1344 * ha: adapter state pointer. 1345 * tq: target queue pointer. 1346 * 1347 * Returns: 1348 * ql local function return status code. 1349 * 1350 * Context: 1351 * Kernel context. 1352 */ 1353 int 1354 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq) 1355 { 1356 int rval; 1357 mbx_cmd_t mc = {0}; 1358 mbx_cmd_t *mcp = &mc; 1359 1360 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1361 1362 mcp->mb[0] = MBC_LOOP_PORT_ENABLE; 1363 1364 if (CFG_IST(ha, CFG_CTRL_2425)) { 1365 mcp->mb[1] = tq->d_id.b.al_pa; 1366 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1367 mcp->mb[1] = tq->loop_id; 1368 } else { 1369 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1370 } 1371 mcp->out_mb = MBX_1|MBX_0; 1372 mcp->in_mb = MBX_0; 1373 mcp->timeout = MAILBOX_TOV; 1374 rval = ql_mailbox_command(ha, mcp); 1375 1376 if (rval != QL_SUCCESS) { 1377 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1378 } else { 1379 /*EMPTY*/ 1380 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1381 } 1382 1383 return (rval); 1384 } 1385 1386 /* 1387 * ql_login_lport 1388 * Issue login loop port mailbox command. 1389 * 1390 * Input: 1391 * ha: adapter state pointer. 1392 * tq: target queue pointer. 1393 * loop_id: FC loop id. 1394 * opt: options. 1395 * LLF_NONE, LLF_PLOGI 1396 * 1397 * Returns: 1398 * ql local function return status code. 1399 * 1400 * Context: 1401 * Kernel context. 1402 */ 1403 int 1404 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1405 uint16_t opt) 1406 { 1407 int rval; 1408 uint16_t flags; 1409 ql_mbx_data_t mr; 1410 mbx_cmd_t mc = {0}; 1411 mbx_cmd_t *mcp = &mc; 1412 1413 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1414 ha->instance, tq->d_id.b24, loop_id); 1415 1416 if (CFG_IST(ha, CFG_CTRL_2425)) { 1417 flags = CF_CMD_PLOGI; 1418 if ((opt & LLF_PLOGI) == 0) { 1419 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1420 } 1421 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr); 1422 } else { 1423 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 1424 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1425 mcp->mb[1] = loop_id; 1426 } else { 1427 mcp->mb[1] = (uint16_t)(loop_id << 8); 1428 } 1429 mcp->mb[2] = opt; 1430 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1431 mcp->in_mb = MBX_0; 1432 mcp->timeout = MAILBOX_TOV; 1433 rval = ql_mailbox_command(ha, mcp); 1434 } 1435 1436 if (rval != QL_SUCCESS) { 1437 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1438 loop_id, rval); 1439 } else { 1440 /*EMPTY*/ 1441 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1442 } 1443 1444 return (rval); 1445 } 1446 1447 /* 1448 * ql_login_fport 1449 * Issue login fabric port mailbox command. 1450 * 1451 * Input: 1452 * ha: adapter state pointer. 1453 * tq: target queue pointer. 1454 * loop_id: FC loop id. 1455 * opt: options. 1456 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI 1457 * mr: pointer for mailbox data. 1458 * 1459 * Returns: 1460 * ql local function return status code. 1461 * 1462 * Context: 1463 * Kernel context. 1464 */ 1465 int 1466 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1467 uint16_t opt, ql_mbx_data_t *mr) 1468 { 1469 int rval; 1470 uint16_t flags; 1471 mbx_cmd_t mc = {0}; 1472 mbx_cmd_t *mcp = &mc; 1473 1474 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1475 ha->instance, tq->d_id.b24, loop_id); 1476 1477 if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) { 1478 opt = (uint16_t)(opt | LFF_NO_PRLI); 1479 } 1480 1481 if (CFG_IST(ha, CFG_CTRL_2425)) { 1482 flags = CF_CMD_PLOGI; 1483 if (opt & LFF_NO_PLOGI) { 1484 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1485 } 1486 if (opt & LFF_NO_PRLI) { 1487 flags = (uint16_t)(flags | CFO_SKIP_PRLI); 1488 } 1489 rval = ql_log_iocb(ha, tq, loop_id, flags, mr); 1490 } else { 1491 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1492 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1493 mcp->mb[1] = loop_id; 1494 mcp->mb[10] = opt; 1495 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 1496 } else { 1497 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 1498 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1499 } 1500 mcp->mb[2] = MSW(tq->d_id.b24); 1501 mcp->mb[3] = LSW(tq->d_id.b24); 1502 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 1503 mcp->timeout = MAILBOX_TOV; 1504 rval = ql_mailbox_command(ha, mcp); 1505 1506 /* Return mailbox data. */ 1507 if (mr != NULL) { 1508 mr->mb[0] = mcp->mb[0]; 1509 mr->mb[1] = mcp->mb[1]; 1510 mr->mb[2] = mcp->mb[2]; 1511 mr->mb[6] = mcp->mb[6]; 1512 mr->mb[7] = mcp->mb[7]; 1513 } 1514 } 1515 1516 if (rval != QL_SUCCESS) { 1517 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, " 1518 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1], 1519 mr->mb[2]); 1520 } else { 1521 /*EMPTY*/ 1522 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1523 } 1524 1525 return (rval); 1526 } 1527 1528 /* 1529 * ql_logout_fabric_port 1530 * Issue logout fabric port mailbox command. 1531 * 1532 * Input: 1533 * ha: adapter state pointer. 1534 * tq: target queue pointer. 1535 * 1536 * Returns: 1537 * ql local function return status code. 1538 * 1539 * Context: 1540 * Kernel context. 1541 */ 1542 int 1543 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq) 1544 { 1545 int rval; 1546 ql_mbx_data_t mr; 1547 mbx_cmd_t mc = {0}; 1548 mbx_cmd_t *mcp = &mc; 1549 1550 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1551 1552 if (CFG_IST(ha, CFG_CTRL_2425)) { 1553 rval = ql_log_iocb(ha, tq, tq->loop_id, CFO_IMPLICIT_LOGO | 1554 CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE, &mr); 1555 } else { 1556 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 1557 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1558 mcp->mb[1] = tq->loop_id; 1559 mcp->mb[10] = 0; 1560 mcp->out_mb = MBX_10|MBX_1|MBX_0; 1561 } else { 1562 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1563 mcp->out_mb = MBX_1|MBX_0; 1564 } 1565 mcp->in_mb = MBX_0; 1566 mcp->timeout = MAILBOX_TOV; 1567 rval = ql_mailbox_command(ha, mcp); 1568 } 1569 1570 if (rval != QL_SUCCESS) { 1571 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval, 1572 tq->d_id.b24, tq->loop_id); 1573 } else { 1574 /*EMPTY*/ 1575 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1576 } 1577 1578 return (rval); 1579 } 1580 1581 /* 1582 * ql_log_iocb 1583 * Function issues login/logout IOCB. 1584 * 1585 * Input: 1586 * ha: adapter state pointer. 1587 * tq: target queue pointer. 1588 * loop_id: FC Loop ID. 1589 * flags: control flags. 1590 * mr: pointer for mailbox data. 1591 * 1592 * Returns: 1593 * ql local function return status code. 1594 * 1595 * Context: 1596 * Kernel context. 1597 */ 1598 int 1599 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1600 uint16_t flags, ql_mbx_data_t *mr) 1601 { 1602 ql_mbx_iocb_t *pkt; 1603 int rval; 1604 uint32_t pkt_size; 1605 1606 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1607 1608 pkt_size = sizeof (ql_mbx_iocb_t); 1609 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1610 if (pkt == NULL) { 1611 EL(ha, "failed, kmem_zalloc\n"); 1612 return (QL_MEMORY_ALLOC_FAILED); 1613 } 1614 1615 pkt->log.entry_type = LOG_TYPE; 1616 pkt->log.entry_count = 1; 1617 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id); 1618 pkt->log.control_flags = (uint16_t)LE_16(flags); 1619 pkt->log.port_id[0] = tq->d_id.b.al_pa; 1620 pkt->log.port_id[1] = tq->d_id.b.area; 1621 pkt->log.port_id[2] = tq->d_id.b.domain; 1622 pkt->log.vp_index = ha->vp_index; 1623 1624 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1625 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) { 1626 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1627 pkt->log.entry_status, tq->d_id.b24); 1628 rval = QL_FUNCTION_PARAMETER_ERROR; 1629 } 1630 1631 if (rval == QL_SUCCESS) { 1632 if (pkt->log.rsp_size == 0xB) { 1633 LITTLE_ENDIAN_32(&pkt->log.io_param[5]); 1634 tq->cmn_features = MSW(pkt->log.io_param[5]); 1635 LITTLE_ENDIAN_32(&pkt->log.io_param[6]); 1636 tq->conc_sequences = MSW(pkt->log.io_param[6]); 1637 tq->relative_offset = LSW(pkt->log.io_param[6]); 1638 LITTLE_ENDIAN_32(&pkt->log.io_param[9]); 1639 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]); 1640 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]); 1641 LITTLE_ENDIAN_32(&pkt->log.io_param[10]); 1642 tq->class3_open_sequences_per_exch = 1643 MSW(pkt->log.io_param[10]); 1644 tq->prli_payload_length = 0x14; 1645 } 1646 if (mr != NULL) { 1647 LITTLE_ENDIAN_16(&pkt->log.status); 1648 LITTLE_ENDIAN_32(&pkt->log.io_param[0]); 1649 LITTLE_ENDIAN_32(&pkt->log.io_param[1]); 1650 1651 if (pkt->log.status != CS_COMPLETE) { 1652 EL(ha, "failed, status=%xh, iop0=%xh, iop1=" 1653 "%xh\n", pkt->log.status, 1654 pkt->log.io_param[0], 1655 pkt->log.io_param[1]); 1656 1657 switch (pkt->log.io_param[0]) { 1658 case CS0_NO_LINK: 1659 case CS0_FIRMWARE_NOT_READY: 1660 mr->mb[0] = MBS_COMMAND_ERROR; 1661 mr->mb[1] = 1; 1662 break; 1663 case CS0_NO_IOCB: 1664 case CS0_NO_PCB_ALLOCATED: 1665 mr->mb[0] = MBS_COMMAND_ERROR; 1666 mr->mb[1] = 2; 1667 break; 1668 case CS0_NO_EXCH_CTRL_BLK: 1669 mr->mb[0] = MBS_COMMAND_ERROR; 1670 mr->mb[1] = 3; 1671 break; 1672 case CS0_COMMAND_FAILED: 1673 mr->mb[0] = MBS_COMMAND_ERROR; 1674 mr->mb[1] = 4; 1675 switch (LSB(pkt->log.io_param[1])) { 1676 case CS1_PLOGI_RESPONSE_FAILED: 1677 mr->mb[2] = 3; 1678 break; 1679 case CS1_PRLI_FAILED: 1680 mr->mb[2] = 4; 1681 break; 1682 case CS1_PRLI_RESPONSE_FAILED: 1683 mr->mb[2] = 5; 1684 break; 1685 case CS1_COMMAND_LOGGED_OUT: 1686 mr->mb[2] = 7; 1687 break; 1688 case CS1_PLOGI_FAILED: 1689 default: 1690 EL(ha, "log iop1 = %xh\n", 1691 LSB(pkt->log.io_param[1])) 1692 mr->mb[2] = 2; 1693 break; 1694 } 1695 break; 1696 case CS0_PORT_NOT_LOGGED_IN: 1697 mr->mb[0] = MBS_COMMAND_ERROR; 1698 mr->mb[1] = 4; 1699 mr->mb[2] = 7; 1700 break; 1701 case CS0_NO_FLOGI_ACC: 1702 case CS0_NO_FABRIC_PRESENT: 1703 mr->mb[0] = MBS_COMMAND_ERROR; 1704 mr->mb[1] = 5; 1705 break; 1706 case CS0_ELS_REJECT_RECEIVED: 1707 mr->mb[0] = MBS_COMMAND_ERROR; 1708 mr->mb[1] = 0xd; 1709 break; 1710 case CS0_PORT_ID_USED: 1711 mr->mb[0] = MBS_PORT_ID_USED; 1712 mr->mb[1] = LSW(pkt->log.io_param[1]); 1713 break; 1714 case CS0_N_PORT_HANDLE_USED: 1715 mr->mb[0] = MBS_LOOP_ID_USED; 1716 mr->mb[1] = MSW(pkt->log.io_param[1]); 1717 mr->mb[2] = LSW(pkt->log.io_param[1]); 1718 break; 1719 case CS0_NO_N_PORT_HANDLE_AVAILABLE: 1720 mr->mb[0] = MBS_ALL_IDS_IN_USE; 1721 break; 1722 case CS0_CMD_PARAMETER_ERROR: 1723 default: 1724 EL(ha, "pkt->log iop[0]=%xh\n", 1725 pkt->log.io_param[0]); 1726 mr->mb[0] = 1727 MBS_COMMAND_PARAMETER_ERROR; 1728 break; 1729 } 1730 } else { 1731 QL_PRINT_3(CE_CONT, "(%d): status=%xh\n", 1732 ha->instance, pkt->log.status); 1733 1734 mr->mb[0] = MBS_COMMAND_COMPLETE; 1735 mr->mb[1] = (uint16_t) 1736 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0); 1737 if (pkt->log.io_param[0] & BIT_8) { 1738 mr->mb[1] = (uint16_t) 1739 (mr->mb[1] | BIT_1); 1740 } 1741 } 1742 rval = mr->mb[0]; 1743 } 1744 1745 } 1746 1747 kmem_free(pkt, pkt_size); 1748 1749 if (rval != QL_SUCCESS) { 1750 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1751 } else { 1752 /*EMPTY*/ 1753 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1754 } 1755 1756 return (rval); 1757 } 1758 1759 /* 1760 * ql_get_port_database 1761 * Issue get port database mailbox command 1762 * and copy context to device queue. 1763 * 1764 * Input: 1765 * ha: adapter state pointer. 1766 * tq: target queue pointer. 1767 * opt: options. 1768 * PDF_NONE, PDF_PLOGI, PDF_ADISC 1769 * Returns: 1770 * ql local function return status code. 1771 * 1772 * Context: 1773 * Kernel context. 1774 */ 1775 int 1776 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt) 1777 { 1778 int rval; 1779 dma_mem_t mem_desc; 1780 mbx_cmd_t mc = {0}; 1781 mbx_cmd_t *mcp = &mc; 1782 port_database_23_t *pd23; 1783 1784 ASSERT(!MUTEX_HELD(&ha->mutex)); 1785 1786 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1787 1788 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP); 1789 if (pd23 == NULL) { 1790 rval = QL_MEMORY_ALLOC_FAILED; 1791 EL(ha, "failed, rval = %xh\n", rval); 1792 return (rval); 1793 } 1794 1795 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1796 PORT_DATABASE_SIZE)) != QL_SUCCESS) { 1797 return (QL_MEMORY_ALLOC_FAILED); 1798 } 1799 1800 if (CFG_IST(ha, CFG_CTRL_2425)) { 1801 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1802 mcp->mb[1] = tq->loop_id; 1803 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area); 1804 mcp->mb[5] = (uint16_t)tq->d_id.b.domain; 1805 mcp->mb[9] = ha->vp_index; 1806 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC); 1807 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3| 1808 MBX_2|MBX_1|MBX_0; 1809 } else { 1810 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ? 1811 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE); 1812 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1813 mcp->mb[1] = tq->loop_id; 1814 mcp->mb[10] = opt; 1815 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3| 1816 MBX_2|MBX_1|MBX_0; 1817 } else { 1818 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt); 1819 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1820 } 1821 } 1822 1823 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1824 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1825 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1826 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1827 mcp->in_mb = MBX_0; 1828 mcp->timeout = MAILBOX_TOV; 1829 rval = ql_mailbox_command(ha, mcp); 1830 1831 if (rval == QL_SUCCESS) { 1832 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23); 1833 } 1834 1835 ql_free_dma_resource(ha, &mem_desc); 1836 1837 if (rval == QL_SUCCESS) { 1838 if (CFG_IST(ha, CFG_CTRL_2425)) { 1839 port_database_24_t *pd24 = (port_database_24_t *)pd23; 1840 1841 tq->master_state = pd24->current_login_state; 1842 tq->slave_state = pd24->last_stable_login_state; 1843 if (PD_PORT_LOGIN(tq)) { 1844 /* Names are big endian. */ 1845 bcopy((void *)&pd24->port_name[0], 1846 (void *)&tq->port_name[0], 8); 1847 bcopy((void *)&pd24->node_name[0], 1848 (void *)&tq->node_name[0], 8); 1849 tq->hard_addr.b.al_pa = pd24->hard_address[2]; 1850 tq->hard_addr.b.area = pd24->hard_address[1]; 1851 tq->hard_addr.b.domain = pd24->hard_address[0]; 1852 tq->class3_rcv_data_size = 1853 pd24->receive_data_size; 1854 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1855 tq->prli_svc_param_word_0 = 1856 pd24->PRLI_service_parameter_word_0; 1857 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1858 tq->prli_svc_param_word_3 = 1859 pd24->PRLI_service_parameter_word_3; 1860 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1861 } 1862 } else { 1863 tq->master_state = pd23->master_state; 1864 tq->slave_state = pd23->slave_state; 1865 if (PD_PORT_LOGIN(tq)) { 1866 /* Names are big endian. */ 1867 bcopy((void *)&pd23->port_name[0], 1868 (void *)&tq->port_name[0], 8); 1869 bcopy((void *)&pd23->node_name[0], 1870 (void *)&tq->node_name[0], 8); 1871 tq->hard_addr.b.al_pa = pd23->hard_address[2]; 1872 tq->hard_addr.b.area = pd23->hard_address[1]; 1873 tq->hard_addr.b.domain = pd23->hard_address[0]; 1874 tq->cmn_features = pd23->common_features; 1875 LITTLE_ENDIAN_16(&tq->cmn_features); 1876 tq->conc_sequences = 1877 pd23->total_concurrent_sequences; 1878 LITTLE_ENDIAN_16(&tq->conc_sequences); 1879 tq->relative_offset = 1880 pd23->RO_by_information_category; 1881 LITTLE_ENDIAN_16(&tq->relative_offset); 1882 tq->class3_recipient_ctl = pd23->recipient; 1883 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl); 1884 tq->class3_rcv_data_size = 1885 pd23->receive_data_size; 1886 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1887 tq->class3_conc_sequences = 1888 pd23->concurrent_sequences; 1889 LITTLE_ENDIAN_16(&tq->class3_conc_sequences); 1890 tq->class3_open_sequences_per_exch = 1891 pd23->open_sequences_per_exchange; 1892 LITTLE_ENDIAN_16( 1893 &tq->class3_open_sequences_per_exch); 1894 tq->prli_payload_length = 1895 pd23->PRLI_payload_length; 1896 LITTLE_ENDIAN_16(&tq->prli_payload_length); 1897 tq->prli_svc_param_word_0 = 1898 pd23->PRLI_service_parameter_word_0; 1899 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1900 tq->prli_svc_param_word_3 = 1901 pd23->PRLI_service_parameter_word_3; 1902 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1903 } 1904 } 1905 1906 if (!PD_PORT_LOGIN(tq)) { 1907 EL(ha, "d_id=%xh, loop_id=%xh, not logged in " 1908 "master=%xh, slave=%xh\n", tq->d_id.b24, 1909 tq->loop_id, tq->master_state, tq->slave_state); 1910 rval = QL_FUNCTION_FAILED; 1911 } else { 1912 tq->flags = tq->prli_svc_param_word_3 & BIT_4 ? 1913 tq->flags & ~TQF_INITIATOR_DEVICE : 1914 tq->flags | TQF_INITIATOR_DEVICE; 1915 1916 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) { 1917 tq->flags = tq->prli_svc_param_word_3 & BIT_8 ? 1918 tq->flags | TQF_TAPE_DEVICE : 1919 tq->flags & ~TQF_TAPE_DEVICE; 1920 } else { 1921 tq->flags &= ~TQF_TAPE_DEVICE; 1922 } 1923 } 1924 } 1925 1926 kmem_free(pd23, PORT_DATABASE_SIZE); 1927 1928 if (rval != QL_SUCCESS) { 1929 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1930 tq->loop_id, rval); 1931 } else { 1932 /*EMPTY*/ 1933 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1934 } 1935 1936 return (rval); 1937 } 1938 1939 /* 1940 * ql_get_loop_position_map 1941 * Issue get loop position map mailbox command. 1942 * 1943 * Input: 1944 * ha: adapter state pointer. 1945 * size: size of data buffer. 1946 * bufp: data pointer for DMA data. 1947 * 1948 * Returns: 1949 * ql local function return status code. 1950 * 1951 * Context: 1952 * Kernel context. 1953 */ 1954 int 1955 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 1956 { 1957 int rval; 1958 dma_mem_t mem_desc; 1959 mbx_cmd_t mc = {0}; 1960 mbx_cmd_t *mcp = &mc; 1961 1962 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1963 1964 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1965 (uint32_t)size)) != QL_SUCCESS) { 1966 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 1967 return (QL_MEMORY_ALLOC_FAILED); 1968 } 1969 1970 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 1971 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1972 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1973 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1974 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1975 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1976 mcp->in_mb = MBX_1|MBX_0; 1977 mcp->timeout = MAILBOX_TOV; 1978 rval = ql_mailbox_command(ha, mcp); 1979 1980 if (rval == QL_SUCCESS) { 1981 ql_get_mbox_dma_data(&mem_desc, bufp); 1982 } 1983 1984 ql_free_dma_resource(ha, &mem_desc); 1985 1986 if (rval != QL_SUCCESS) { 1987 EL(ha, "failed=%xh\n", rval); 1988 } else { 1989 /*EMPTY*/ 1990 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1991 } 1992 1993 return (rval); 1994 } 1995 1996 /* 1997 * ql_set_rnid_params 1998 * Issue set RNID parameters mailbox command. 1999 * 2000 * Input: 2001 * ha: adapter state pointer. 2002 * size: size of data buffer. 2003 * bufp: data pointer for DMA data. 2004 * 2005 * Returns: 2006 * ql local function return status code. 2007 * 2008 * Context: 2009 * Kernel context. 2010 */ 2011 int 2012 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2013 { 2014 int rval; 2015 dma_mem_t mem_desc; 2016 mbx_cmd_t mc = {0}; 2017 mbx_cmd_t *mcp = &mc; 2018 2019 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2020 2021 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp, 2022 (uint32_t)size)) != QL_SUCCESS) { 2023 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval); 2024 return (rval); 2025 } 2026 2027 mcp->mb[0] = MBC_SET_PARAMETERS; 2028 mcp->mb[1] = 0; 2029 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2030 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2031 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2032 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2033 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2034 mcp->in_mb = MBX_0; 2035 mcp->timeout = MAILBOX_TOV; 2036 rval = ql_mailbox_command(ha, mcp); 2037 2038 ql_free_dma_resource(ha, &mem_desc); 2039 2040 if (rval != QL_SUCCESS) { 2041 EL(ha, "failed, rval = %xh\n", rval); 2042 } else { 2043 /*EMPTY*/ 2044 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2045 } 2046 2047 return (rval); 2048 } 2049 2050 /* 2051 * ql_send_rnid_els 2052 * Issue a send node identfication data mailbox command. 2053 * 2054 * Input: 2055 * ha: adapter state pointer. 2056 * loop_id: FC loop id. 2057 * opt: options. 2058 * size: size of data buffer. 2059 * bufp: data pointer for DMA data. 2060 * 2061 * Returns: 2062 * ql local function return status code. 2063 * 2064 * Context: 2065 * Kernel context. 2066 */ 2067 int 2068 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt, 2069 size_t size, caddr_t bufp) 2070 { 2071 int rval; 2072 dma_mem_t mem_desc; 2073 mbx_cmd_t mc = {0}; 2074 mbx_cmd_t *mcp = &mc; 2075 2076 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2077 2078 bzero((caddr_t)mcp, sizeof (mbx_cmd_t)); 2079 2080 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2081 (uint32_t)size)) != QL_SUCCESS) { 2082 return (QL_MEMORY_ALLOC_FAILED); 2083 } 2084 2085 mcp->mb[0] = MBC_SEND_RNID_ELS; 2086 if (CFG_IST(ha, CFG_CTRL_2425)) { 2087 mcp->mb[1] = loop_id; 2088 mcp->mb[9] = ha->vp_index; 2089 mcp->mb[10] = opt; 2090 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2091 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2092 mcp->mb[1] = loop_id; 2093 mcp->mb[10] = opt; 2094 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2095 } else { 2096 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 2097 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2098 } 2099 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2100 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2101 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2102 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2103 mcp->in_mb = 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, rval = %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_get_rnid_params 2125 * Issue get 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_get_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_resources(ha, &mem_desc, 2149 (uint32_t)size)) != QL_SUCCESS) { 2150 return (QL_MEMORY_ALLOC_FAILED); 2151 } 2152 2153 mcp->mb[0] = MBC_GET_PARAMETERS; 2154 mcp->mb[1] = 0; 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 if (rval == QL_SUCCESS) { 2165 ql_get_mbox_dma_data(&mem_desc, bufp); 2166 } 2167 2168 ql_free_dma_resource(ha, &mem_desc); 2169 2170 if (rval != QL_SUCCESS) { 2171 EL(ha, "failed=%xh\n", rval); 2172 } else { 2173 /*EMPTY*/ 2174 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2175 } 2176 2177 return (rval); 2178 } 2179 2180 /* 2181 * ql_get_link_status 2182 * Issue get link status mailbox command. 2183 * 2184 * Input: 2185 * ha: adapter state pointer. 2186 * loop_id: FC loop id or n_port_hdl. 2187 * size: size of data buffer. 2188 * bufp: data pointer for DMA data. 2189 * port_no: port number to query. 2190 * 2191 * Returns: 2192 * ql local function return status code. 2193 * 2194 * Context: 2195 * Kernel context. 2196 */ 2197 int 2198 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2199 caddr_t bufp, uint8_t port_no) 2200 { 2201 dma_mem_t mem_desc; 2202 mbx_cmd_t mc = {0}; 2203 mbx_cmd_t *mcp = &mc; 2204 int rval = QL_SUCCESS; 2205 int retry = 0; 2206 2207 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2208 2209 do { 2210 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2211 (uint32_t)size)) != QL_SUCCESS) { 2212 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2213 return (QL_MEMORY_ALLOC_FAILED); 2214 } 2215 2216 mcp->mb[0] = MBC_GET_LINK_STATUS; 2217 if (CFG_IST(ha, CFG_CTRL_2425)) { 2218 if (loop_id == ha->loop_id) { 2219 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2220 mcp->mb[8] = (uint16_t)(size >> 2); 2221 mcp->mb[10] = 0; 2222 mcp->out_mb = MBX_10|MBX_8; 2223 } else { 2224 mcp->mb[1] = loop_id; 2225 mcp->mb[4] = port_no; 2226 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0); 2227 mcp->out_mb = MBX_10|MBX_4; 2228 } 2229 } else { 2230 if (retry) { 2231 port_no = (uint8_t)(port_no | BIT_3); 2232 } 2233 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2234 mcp->mb[1] = loop_id; 2235 mcp->mb[10] = port_no; 2236 mcp->out_mb = MBX_10; 2237 } else { 2238 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2239 port_no); 2240 mcp->out_mb = 0; 2241 } 2242 } 2243 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2244 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2245 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2246 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2247 mcp->in_mb = MBX_1|MBX_0; 2248 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2249 mcp->timeout = MAILBOX_TOV; 2250 2251 rval = ql_mailbox_command(ha, mcp); 2252 2253 if (rval == QL_SUCCESS) { 2254 ql_get_mbox_dma_data(&mem_desc, bufp); 2255 } 2256 2257 ql_free_dma_resource(ha, &mem_desc); 2258 2259 if (rval != QL_SUCCESS) { 2260 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2261 } 2262 2263 /* 2264 * Some of the devices want d_id in the payload, 2265 * strictly as per standard. Let's retry. 2266 */ 2267 2268 } while (rval == QL_COMMAND_ERROR && !retry++); 2269 2270 if (rval != QL_SUCCESS) { 2271 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2272 } else { 2273 /*EMPTY*/ 2274 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2275 } 2276 2277 return (rval); 2278 } 2279 2280 /* 2281 * ql_get_status_counts 2282 * Issue get adapter link status counts mailbox command. 2283 * 2284 * Input: 2285 * ha: adapter state pointer. 2286 * loop_id: FC loop id or n_port_hdl. 2287 * size: size of data buffer. 2288 * bufp: data pointer for DMA data. 2289 * port_no: port number to query. 2290 * 2291 * Returns: 2292 * ql local function return status code. 2293 * 2294 * Context: 2295 * Kernel context. 2296 */ 2297 int 2298 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2299 caddr_t bufp, uint8_t port_no) 2300 { 2301 dma_mem_t mem_desc; 2302 mbx_cmd_t mc = {0}; 2303 mbx_cmd_t *mcp = &mc; 2304 int rval = QL_SUCCESS; 2305 2306 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2307 2308 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2309 (uint32_t)size)) != QL_SUCCESS) { 2310 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval); 2311 return (QL_MEMORY_ALLOC_FAILED); 2312 } 2313 2314 if (CFG_IST(ha, CFG_CTRL_2425)) { 2315 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2316 mcp->mb[8] = (uint16_t)(size / 4); 2317 mcp->mb[10] = 0; 2318 mcp->out_mb = MBX_10|MBX_8; 2319 } else { 2320 mcp->mb[0] = MBC_GET_LINK_STATUS; 2321 2322 /* allows reporting when link is down */ 2323 if (CFG_IST(ha, CFG_CTRL_2200) == 0) { 2324 port_no = (uint8_t)(port_no | BIT_6); 2325 } 2326 2327 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2328 mcp->mb[1] = loop_id; 2329 mcp->mb[10] = port_no; 2330 mcp->out_mb = MBX_10|MBX_1; 2331 } else { 2332 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2333 port_no); 2334 mcp->out_mb = MBX_1; 2335 } 2336 } 2337 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2338 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2339 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2340 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2341 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2342 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2343 mcp->timeout = MAILBOX_TOV; 2344 rval = ql_mailbox_command(ha, mcp); 2345 2346 if (rval == QL_SUCCESS) { 2347 ql_get_mbox_dma_data(&mem_desc, bufp); 2348 } 2349 2350 ql_free_dma_resource(ha, &mem_desc); 2351 2352 if (rval != QL_SUCCESS) { 2353 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval, 2354 mcp->mb[1], mcp->mb[2]); 2355 } else { 2356 /*EMPTY*/ 2357 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2358 } 2359 2360 return (rval); 2361 } 2362 2363 /* 2364 * ql_reset_link_status 2365 * Issue Reset Link Error Status mailbox command 2366 * 2367 * Input: 2368 * ha: adapter state pointer. 2369 * 2370 * Returns: 2371 * ql local function return status code. 2372 * 2373 * Context: 2374 * Kernel context. 2375 */ 2376 int 2377 ql_reset_link_status(ql_adapter_state_t *ha) 2378 { 2379 int rval; 2380 mbx_cmd_t mc = {0}; 2381 mbx_cmd_t *mcp = &mc; 2382 2383 QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance); 2384 2385 mcp->mb[0] = MBC_RESET_LINK_STATUS; 2386 mcp->out_mb = MBX_0; 2387 mcp->in_mb = MBX_0; 2388 mcp->timeout = MAILBOX_TOV; 2389 rval = ql_mailbox_command(ha, mcp); 2390 2391 if (rval != QL_SUCCESS) { 2392 EL(ha, "failed=%xh\n", rval); 2393 } else { 2394 /*EMPTY*/ 2395 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2396 } 2397 2398 return (rval); 2399 } 2400 2401 /* 2402 * ql_loop_reset 2403 * Issue loop reset. 2404 * 2405 * Input: 2406 * ha: adapter state pointer. 2407 * 2408 * Returns: 2409 * ql local function return status code. 2410 * 2411 * Context: 2412 * Kernel context. 2413 */ 2414 int 2415 ql_loop_reset(ql_adapter_state_t *ha) 2416 { 2417 int rval; 2418 2419 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2420 2421 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) { 2422 rval = ql_lip_reset(ha, 0xff); 2423 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) { 2424 rval = ql_full_login_lip(ha); 2425 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) { 2426 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay); 2427 } else { 2428 rval = ql_initiate_lip(ha); 2429 } 2430 2431 if (rval != QL_SUCCESS) { 2432 EL(ha, "failed, rval = %xh\n", rval); 2433 } else { 2434 /*EMPTY*/ 2435 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2436 } 2437 2438 return (rval); 2439 } 2440 2441 /* 2442 * ql_initiate_lip 2443 * Initiate LIP mailbox command. 2444 * 2445 * Input: 2446 * ha: adapter state pointer. 2447 * 2448 * Returns: 2449 * ql local function return status code. 2450 * 2451 * Context: 2452 * Kernel context. 2453 */ 2454 int 2455 ql_initiate_lip(ql_adapter_state_t *ha) 2456 { 2457 int rval; 2458 mbx_cmd_t mc = {0}; 2459 mbx_cmd_t *mcp = &mc; 2460 2461 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2462 2463 if (CFG_IST(ha, CFG_CTRL_2425)) { 2464 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2465 mcp->mb[1] = BIT_4; 2466 mcp->mb[2] = 0; 2467 mcp->mb[3] = ha->loop_reset_delay; 2468 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2469 } else { 2470 mcp->mb[0] = MBC_INITIATE_LIP; 2471 mcp->out_mb = MBX_0; 2472 } 2473 mcp->in_mb = MBX_0; 2474 mcp->timeout = MAILBOX_TOV; 2475 rval = ql_mailbox_command(ha, mcp); 2476 2477 if (rval != QL_SUCCESS) { 2478 EL(ha, "failed, rval = %xh\n", rval); 2479 } else { 2480 /*EMPTY*/ 2481 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2482 } 2483 2484 return (rval); 2485 } 2486 2487 /* 2488 * ql_full_login_lip 2489 * Issue full login LIP mailbox command. 2490 * 2491 * Input: 2492 * ha: adapter state pointer. 2493 * 2494 * Returns: 2495 * ql local function return status code. 2496 * 2497 * Context: 2498 * Kernel context. 2499 */ 2500 int 2501 ql_full_login_lip(ql_adapter_state_t *ha) 2502 { 2503 int rval; 2504 mbx_cmd_t mc = {0}; 2505 mbx_cmd_t *mcp = &mc; 2506 2507 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2508 2509 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2510 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ? BIT_3 : 0); 2511 mcp->mb[2] = 0; 2512 mcp->mb[3] = 0; 2513 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2514 mcp->in_mb = MBX_0; 2515 mcp->timeout = MAILBOX_TOV; 2516 rval = ql_mailbox_command(ha, mcp); 2517 2518 if (rval != QL_SUCCESS) { 2519 EL(ha, "failed, rval = %xh\n", rval); 2520 } else { 2521 /*EMPTY*/ 2522 QL_PRINT_3(CE_CONT, "(%d): done", ha->instance); 2523 } 2524 2525 return (rval); 2526 } 2527 2528 /* 2529 * ql_lip_reset 2530 * Issue lip reset to a port. 2531 * 2532 * Input: 2533 * ha: adapter state pointer. 2534 * loop_id: FC loop id. 2535 * 2536 * Returns: 2537 * ql local function return status code. 2538 * 2539 * Context: 2540 * Kernel context. 2541 */ 2542 int 2543 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id) 2544 { 2545 int rval; 2546 mbx_cmd_t mc = {0}; 2547 mbx_cmd_t *mcp = &mc; 2548 2549 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2550 2551 if (CFG_IST(ha, CFG_CTRL_2425)) { 2552 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2553 mcp->mb[1] = BIT_6; 2554 mcp->mb[2] = 0; 2555 mcp->mb[3] = ha->loop_reset_delay; 2556 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2557 } else { 2558 mcp->mb[0] = MBC_LIP_RESET; 2559 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2560 mcp->mb[1] = loop_id; 2561 mcp->mb[10] = 0; 2562 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 2563 } else { 2564 mcp->mb[1] = (uint16_t)(loop_id << 8); 2565 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2566 } 2567 mcp->mb[2] = ha->loop_reset_delay; 2568 mcp->mb[3] = 0; 2569 } 2570 mcp->in_mb = MBX_0; 2571 mcp->timeout = MAILBOX_TOV; 2572 rval = ql_mailbox_command(ha, mcp); 2573 2574 if (rval != QL_SUCCESS) { 2575 EL(ha, "failed, rval = %xh\n", rval); 2576 } else { 2577 /*EMPTY*/ 2578 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2579 } 2580 2581 return (rval); 2582 } 2583 2584 /* 2585 * ql_abort_command 2586 * Abort command aborts a specified IOCB. 2587 * 2588 * Input: 2589 * ha: adapter state pointer. 2590 * sp: SRB structure pointer. 2591 * 2592 * Returns: 2593 * ql local function return status code. 2594 * 2595 * Context: 2596 * Kernel context. 2597 */ 2598 int 2599 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp) 2600 { 2601 int rval; 2602 mbx_cmd_t mc = {0}; 2603 mbx_cmd_t *mcp = &mc; 2604 ql_tgt_t *tq = sp->lun_queue->target_queue; 2605 2606 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2607 2608 if (CFG_IST(ha, CFG_CTRL_2425)) { 2609 rval = ql_abort_cmd_iocb(ha, sp); 2610 } else { 2611 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB; 2612 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2613 mcp->mb[1] = tq->loop_id; 2614 } else { 2615 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 2616 } 2617 mcp->mb[2] = LSW(sp->handle); 2618 mcp->mb[3] = MSW(sp->handle); 2619 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ? 2620 sp->lun_queue->lun_no : 0); 2621 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2622 mcp->in_mb = MBX_0; 2623 mcp->timeout = MAILBOX_TOV; 2624 rval = ql_mailbox_command(ha, mcp); 2625 } 2626 2627 if (rval != QL_SUCCESS) { 2628 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval, 2629 tq->d_id.b24, sp->handle); 2630 } else { 2631 /*EMPTY*/ 2632 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2633 } 2634 2635 return (rval); 2636 } 2637 2638 /* 2639 * ql_abort_cmd_iocb 2640 * Function issues abort command IOCB. 2641 * 2642 * Input: 2643 * ha: adapter state pointer. 2644 * sp: SRB structure pointer. 2645 * 2646 * Returns: 2647 * ql local function return status code. 2648 * 2649 * Context: 2650 * Interrupt or Kernel context, no mailbox commands allowed. 2651 */ 2652 static int 2653 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp) 2654 { 2655 ql_mbx_iocb_t *pkt; 2656 int rval; 2657 uint32_t pkt_size; 2658 uint16_t comp_status; 2659 ql_tgt_t *tq = sp->lun_queue->target_queue; 2660 2661 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2662 2663 pkt_size = sizeof (ql_mbx_iocb_t); 2664 if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) { 2665 EL(ha, "failed, kmem_zalloc\n"); 2666 return (QL_MEMORY_ALLOC_FAILED); 2667 } 2668 2669 pkt->abo.entry_type = ABORT_CMD_TYPE; 2670 pkt->abo.entry_count = 1; 2671 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 2672 pkt->abo.options = AF_NO_ABTS; 2673 pkt->abo.cmd_handle = LE_32(sp->handle); 2674 pkt->abo.target_id[0] = tq->d_id.b.al_pa; 2675 pkt->abo.target_id[1] = tq->d_id.b.area; 2676 pkt->abo.target_id[2] = tq->d_id.b.domain; 2677 pkt->abo.vp_index = ha->vp_index; 2678 2679 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 2680 2681 if (rval == QL_SUCCESS && (pkt->abo.entry_status & 0x3c) != 0) { 2682 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 2683 pkt->abo.entry_status, tq->d_id.b24); 2684 rval = QL_FUNCTION_PARAMETER_ERROR; 2685 } 2686 2687 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl); 2688 if (rval == QL_SUCCESS && comp_status != CS_COMPLETE) { 2689 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 2690 comp_status, tq->d_id.b24); 2691 rval = QL_FUNCTION_FAILED; 2692 } 2693 2694 kmem_free(pkt, pkt_size); 2695 2696 if (rval != QL_SUCCESS) { 2697 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 2698 } else { 2699 /*EMPTY*/ 2700 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2701 } 2702 2703 return (rval); 2704 } 2705 2706 /* 2707 * ql_verify_checksum 2708 * Verify loaded RISC firmware. 2709 * 2710 * Input: 2711 * ha = adapter state pointer. 2712 * 2713 * Returns: 2714 * ql local function return status code. 2715 * 2716 * Context: 2717 * Kernel context. 2718 */ 2719 int 2720 ql_verify_checksum(ql_adapter_state_t *ha) 2721 { 2722 int rval; 2723 mbx_cmd_t mc = {0}; 2724 mbx_cmd_t *mcp = &mc; 2725 2726 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2727 2728 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 2729 if (CFG_IST(ha, CFG_CTRL_2425)) { 2730 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 2731 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 2732 } else { 2733 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 2734 } 2735 mcp->out_mb = MBX_2|MBX_1|MBX_0; 2736 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2737 mcp->timeout = MAILBOX_TOV; 2738 rval = ql_mailbox_command(ha, mcp); 2739 2740 if (rval != QL_SUCCESS) { 2741 EL(ha, "failed, rval = %xh\n", rval); 2742 } else { 2743 /*EMPTY*/ 2744 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2745 } 2746 2747 return (rval); 2748 } 2749 2750 /* 2751 * ql_get_id_list 2752 * Get d_id and loop ID list. 2753 * 2754 * Input: 2755 * ha: adapter state pointer. 2756 * bp: data pointer for DMA data. 2757 * size: size of data buffer. 2758 * mr: pointer for mailbox data. 2759 * 2760 * Returns: 2761 * ql local function return status code. 2762 * 2763 * Context: 2764 * Kernel context. 2765 */ 2766 int 2767 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, 2768 ql_mbx_data_t *mr) 2769 { 2770 int rval; 2771 dma_mem_t mem_desc; 2772 mbx_cmd_t mc = {0}; 2773 mbx_cmd_t *mcp = &mc; 2774 2775 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2776 2777 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2778 (uint32_t)size)) != QL_SUCCESS) { 2779 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2780 return (QL_MEMORY_ALLOC_FAILED); 2781 } 2782 2783 mcp->mb[0] = MBC_GET_ID_LIST; 2784 if (CFG_IST(ha, CFG_CTRL_2425)) { 2785 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2786 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2787 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2788 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2789 mcp->mb[8] = (uint16_t)size; 2790 mcp->mb[9] = ha->vp_index; 2791 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2792 } else { 2793 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2794 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2795 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2796 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2797 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2798 } 2799 mcp->in_mb = MBX_1|MBX_0; 2800 mcp->timeout = MAILBOX_TOV; 2801 rval = ql_mailbox_command(ha, mcp); 2802 2803 if (rval == QL_SUCCESS) { 2804 ql_get_mbox_dma_data(&mem_desc, bp); 2805 } 2806 2807 ql_free_dma_resource(ha, &mem_desc); 2808 2809 /* Return mailbox data. */ 2810 if (mr != NULL) { 2811 mr->mb[0] = mcp->mb[0]; 2812 mr->mb[1] = mcp->mb[1]; 2813 } 2814 2815 if (rval != QL_SUCCESS) { 2816 EL(ha, "failed, rval = %xh\n", rval); 2817 } else { 2818 /*EMPTY*/ 2819 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2820 } 2821 2822 return (rval); 2823 } 2824 2825 /* 2826 * ql_wrt_risc_ram 2827 * Load RISC RAM. 2828 * 2829 * Input: 2830 * ha: adapter state pointer. 2831 * risc_address: risc ram word address. 2832 * bp: DMA pointer. 2833 * word_count: 16/32bit word count. 2834 * 2835 * Returns: 2836 * ql local function return status code. 2837 * 2838 * Context: 2839 * Kernel context. 2840 */ 2841 int 2842 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 2843 uint32_t word_count) 2844 { 2845 int rval; 2846 mbx_cmd_t mc = {0}; 2847 mbx_cmd_t *mcp = &mc; 2848 2849 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2850 2851 if (CFG_IST(ha, CFG_CTRL_2425)) { 2852 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED; 2853 mcp->mb[4] = MSW(word_count); 2854 mcp->mb[5] = LSW(word_count); 2855 mcp->mb[6] = MSW(MSD(bp)); 2856 mcp->mb[7] = LSW(MSD(bp)); 2857 mcp->mb[8] = MSW(risc_address); 2858 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 2859 MBX_0; 2860 } else { 2861 mcp->mb[0] = MBC_LOAD_RAM; 2862 mcp->mb[4] = LSW(word_count); 2863 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2864 } 2865 mcp->mb[1] = LSW(risc_address); 2866 mcp->mb[2] = MSW(LSD(bp)); 2867 mcp->mb[3] = LSW(LSD(bp)); 2868 mcp->in_mb = MBX_0; 2869 mcp->timeout = MAILBOX_TOV; 2870 2871 rval = ql_mailbox_command(ha, mcp); 2872 2873 if (rval != QL_SUCCESS) { 2874 EL(ha, "failed, rval = %xh\n", rval); 2875 } else { 2876 /*EMPTY*/ 2877 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2878 } 2879 2880 return (rval); 2881 } 2882 2883 /* 2884 * ql_rd_risc_ram 2885 * Get RISC RAM. 2886 * 2887 * Input: 2888 * ha: adapter state pointer. 2889 * risc_address: risc ram word address. 2890 * bp: direct data pointer. 2891 * word_count: 16/32bit word count. 2892 * 2893 * Returns: 2894 * ql local function return status code. 2895 * 2896 * Context: 2897 * Kernel context. 2898 */ 2899 int 2900 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 2901 uint32_t word_count) 2902 { 2903 int rval; 2904 mbx_cmd_t mc = {0}; 2905 mbx_cmd_t *mcp = &mc; 2906 2907 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2908 2909 if (CFG_IST(ha, CFG_CTRL_2425)) { 2910 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED; 2911 mcp->mb[1] = LSW(risc_address); 2912 mcp->mb[2] = MSW(LSD(bp)); 2913 mcp->mb[3] = LSW(LSD(bp)); 2914 mcp->mb[4] = MSW(word_count); 2915 mcp->mb[5] = LSW(word_count); 2916 mcp->mb[6] = MSW(MSD(bp)); 2917 mcp->mb[7] = LSW(MSD(bp)); 2918 mcp->mb[8] = MSW(risc_address); 2919 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 2920 MBX_0; 2921 } else { 2922 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */ 2923 mcp->mb[1] = LSW(risc_address); 2924 mcp->mb[2] = MSW(LSD(bp)); 2925 mcp->mb[3] = LSW(LSD(bp)); 2926 mcp->mb[4] = LSW(word_count); 2927 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2928 } 2929 mcp->in_mb = MBX_0; 2930 mcp->timeout = MAILBOX_TOV; 2931 rval = ql_mailbox_command(ha, mcp); 2932 2933 if (rval != QL_SUCCESS) { 2934 EL(ha, "failed, rval = %xh\n", rval); 2935 } else { 2936 /*EMPTY*/ 2937 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2938 } 2939 2940 return (rval); 2941 } 2942 2943 /* 2944 * ql_issue_mbx_iocb 2945 * Issue IOCB using mailbox command 2946 * 2947 * Input: 2948 * ha: adapter state pointer. 2949 * bp: buffer pointer. 2950 * size: buffer size. 2951 * 2952 * Returns: 2953 * ql local function return status code. 2954 * 2955 * Context: 2956 * Kernel context. 2957 */ 2958 int 2959 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size) 2960 { 2961 int rval; 2962 dma_mem_t mem_desc; 2963 mbx_cmd_t mc = {0}; 2964 mbx_cmd_t *mcp = &mc; 2965 2966 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2967 2968 2969 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 2970 QL_SUCCESS) { 2971 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 2972 return (rval); 2973 } 2974 2975 mcp->mb[0] = MBC_EXECUTE_IOCB; 2976 mcp->mb[1] = 0; 2977 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2978 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2979 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2980 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2981 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2982 mcp->in_mb = MBX_1|MBX_0; 2983 mcp->timeout = MAILBOX_TOV + 5; 2984 rval = ql_mailbox_command(ha, mcp); 2985 2986 if (rval == QL_SUCCESS) { 2987 ql_get_mbox_dma_data(&mem_desc, bp); 2988 } 2989 2990 ql_free_dma_resource(ha, &mem_desc); 2991 2992 if (rval != QL_SUCCESS) { 2993 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2994 } else { 2995 /*EMPTY*/ 2996 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2997 } 2998 2999 return (rval); 3000 } 3001 3002 /* 3003 * ql_mbx_wrap_test 3004 * Mailbox register wrap test. 3005 * 3006 * Input: 3007 * ha: adapter state pointer. 3008 * mr: pointer for in/out mailbox data. 3009 * 3010 * Returns: 3011 * ql local function return status code. 3012 * 3013 * Context: 3014 * Kernel context. 3015 */ 3016 int 3017 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3018 { 3019 int rval; 3020 mbx_cmd_t mc = {0}; 3021 mbx_cmd_t *mcp = &mc; 3022 3023 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3024 3025 if (mr != NULL) { 3026 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 3027 mcp->mb[1] = mr->mb[1]; 3028 mcp->mb[2] = mr->mb[2]; 3029 mcp->mb[3] = mr->mb[3]; 3030 mcp->mb[4] = mr->mb[4]; 3031 mcp->mb[5] = mr->mb[5]; 3032 mcp->mb[6] = mr->mb[6]; 3033 mcp->mb[7] = mr->mb[7]; 3034 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3035 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3036 mcp->timeout = MAILBOX_TOV; 3037 rval = ql_mailbox_command(ha, mcp); 3038 if (rval == QL_SUCCESS) { 3039 mr->mb[1] = mcp->mb[1]; 3040 mr->mb[2] = mcp->mb[2]; 3041 mr->mb[3] = mcp->mb[3]; 3042 mr->mb[4] = mcp->mb[4]; 3043 mr->mb[5] = mcp->mb[5]; 3044 mr->mb[6] = mcp->mb[6]; 3045 mr->mb[7] = mcp->mb[7]; 3046 } 3047 } else { 3048 rval = QL_FUNCTION_PARAMETER_ERROR; 3049 } 3050 3051 if (rval != QL_SUCCESS) { 3052 EL(ha, "failed=%xh\n", rval); 3053 } else { 3054 /*EMPTY*/ 3055 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3056 } 3057 3058 return (rval); 3059 } 3060 3061 /* 3062 * ql_execute_fw 3063 * Start adapter firmware. 3064 * 3065 * Input: 3066 * ha: adapter state pointer. 3067 * 3068 * Returns: 3069 * qla2x00 local function return status code. 3070 * 3071 * Context: 3072 * Kernel context. 3073 */ 3074 int 3075 ql_execute_fw(ql_adapter_state_t *ha) 3076 { 3077 int rval; 3078 mbx_cmd_t mc = {0}; 3079 mbx_cmd_t *mcp = &mc; 3080 3081 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3082 3083 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 3084 if (CFG_IST(ha, CFG_CTRL_2425)) { 3085 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 3086 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 3087 } else { 3088 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 3089 mcp->mb[2] = 0; 3090 } 3091 mcp->mb[3] = 0; 3092 mcp->mb[4] = 0; 3093 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3094 mcp->in_mb = MBX_0; 3095 mcp->timeout = MAILBOX_TOV; 3096 rval = ql_mailbox_command(ha, mcp); 3097 3098 if (CFG_IST(ha, CFG_CTRL_2200)) { 3099 rval = QL_SUCCESS; 3100 } 3101 3102 if (rval != QL_SUCCESS) { 3103 EL(ha, "failed=%xh\n", rval); 3104 } else { 3105 /*EMPTY*/ 3106 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3107 } 3108 3109 return (rval); 3110 } 3111 3112 /* 3113 * ql_get_firmware_option 3114 * Get Firmware Options Mailbox Command. 3115 * 3116 * Input: 3117 * ha: adapter state pointer. 3118 * mr: pointer for mailbox data. 3119 * 3120 * Returns: 3121 * ql local function return status code. 3122 * 3123 * Context: 3124 * Kernel context. 3125 */ 3126 int 3127 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 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_GET_FIRMWARE_OPTIONS; 3136 mcp->out_mb = MBX_0; 3137 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3138 mcp->timeout = MAILBOX_TOV; 3139 rval = ql_mailbox_command(ha, mcp); 3140 3141 /* Return mailbox data. */ 3142 if (mr != NULL) { 3143 mr->mb[0] = mcp->mb[0]; 3144 mr->mb[1] = mcp->mb[1]; 3145 mr->mb[2] = mcp->mb[2]; 3146 mr->mb[3] = mcp->mb[3]; 3147 } 3148 3149 if (rval != QL_SUCCESS) { 3150 EL(ha, "failed=%xh\n", rval); 3151 } else { 3152 /*EMPTY*/ 3153 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 3154 } 3155 3156 return (rval); 3157 } 3158 3159 /* 3160 * ql_set_firmware_option 3161 * Set Firmware Options Mailbox Command. 3162 * 3163 * Input: 3164 * ha: adapter state pointer. 3165 * mr: pointer for mailbox data. 3166 * 3167 * Returns: 3168 * ql local function return status code. 3169 * 3170 * Context: 3171 * Kernel context. 3172 */ 3173 int 3174 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3175 { 3176 int rval; 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 (mr != NULL) { 3183 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS; 3184 mcp->mb[1] = mr->mb[1]; 3185 mcp->mb[2] = mr->mb[2]; 3186 mcp->mb[3] = mr->mb[3]; 3187 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3188 mcp->in_mb = MBX_0; 3189 mcp->timeout = MAILBOX_TOV; 3190 rval = ql_mailbox_command(ha, mcp); 3191 } else { 3192 rval = QL_FUNCTION_PARAMETER_ERROR; 3193 } 3194 3195 if (rval != QL_SUCCESS) { 3196 EL(ha, "failed=%xh\n", rval); 3197 } else { 3198 /*EMPTY*/ 3199 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3200 } 3201 3202 return (rval); 3203 } 3204 3205 /* 3206 * ql_init_firmware 3207 * Initialize firmware mailbox command. 3208 * 3209 * Input: 3210 * ha: adapter state pointer. 3211 * ha->init_ctrl_blk = setup for transmit. 3212 * 3213 * Returns: 3214 * ql local function return status code. 3215 * 3216 * Context: 3217 * Kernel context. 3218 */ 3219 int 3220 ql_init_firmware(ql_adapter_state_t *ha) 3221 { 3222 int rval; 3223 dma_mem_t mem_desc; 3224 mbx_cmd_t mc = {0}; 3225 mbx_cmd_t *mcp = &mc; 3226 3227 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3228 3229 if (CFG_IST(ha, CFG_CTRL_2425)) { 3230 WRT32_IO_REG(ha, req_in, 0); 3231 WRT32_IO_REG(ha, resp_out, 0); 3232 WRT32_IO_REG(ha, pri_req_in, 0); 3233 WRT32_IO_REG(ha, atio_req_out, 0); 3234 } else { 3235 WRT16_IO_REG(ha, req_in, 0); 3236 WRT16_IO_REG(ha, resp_out, 0); 3237 } 3238 3239 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 3240 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) != 3241 QL_SUCCESS) { 3242 EL(ha, "dma setup failed=%xh\n", rval); 3243 return (rval); 3244 } 3245 3246 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ? 3247 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE); 3248 3249 if (CFG_IST(ha, CFG_SBUS_CARD)) { 3250 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2200) ? 3251 0x204c : 0x52); 3252 } else { 3253 mcp->mb[1] = 0; 3254 } 3255 3256 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3257 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3258 mcp->mb[4] = 0; 3259 mcp->mb[5] = 0; 3260 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3261 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3262 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3263 mcp->in_mb = MBX_0|MBX_2; 3264 mcp->timeout = MAILBOX_TOV; 3265 rval = ql_mailbox_command(ha, mcp); 3266 3267 if (rval == QL_SUCCESS) { 3268 ha->sfp_stat = mcp->mb[2]; 3269 } 3270 ql_free_dma_resource(ha, &mem_desc); 3271 3272 if (rval != QL_SUCCESS) { 3273 EL(ha, "failed=%xh\n", rval); 3274 } else { 3275 /*EMPTY*/ 3276 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3277 } 3278 3279 return (rval); 3280 } 3281 3282 /* 3283 * ql_get_firmware_state 3284 * Get adapter firmware state. 3285 * 3286 * Input: 3287 * ha: adapter state pointer. 3288 * mr: pointer for mailbox data. 3289 * 3290 * Returns: 3291 * ql local function return status code. 3292 * 3293 * Context: 3294 * Kernel context. 3295 */ 3296 int 3297 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3298 { 3299 int rval; 3300 mbx_cmd_t mc = {0}; 3301 mbx_cmd_t *mcp = &mc; 3302 3303 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3304 3305 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 3306 mcp->out_mb = MBX_0; 3307 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3308 mcp->timeout = MAILBOX_TOV; 3309 rval = ql_mailbox_command(ha, mcp); 3310 3311 /* Return mailbox data. */ 3312 if (mr != NULL) { 3313 mr->mb[1] = mcp->mb[1]; 3314 mr->mb[2] = mcp->mb[2]; 3315 mr->mb[3] = mcp->mb[3]; 3316 } 3317 3318 ha->sfp_stat = mcp->mb[2]; 3319 3320 if (rval != QL_SUCCESS) { 3321 EL(ha, "failed=%xh\n", rval); 3322 } else { 3323 /*EMPTY*/ 3324 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3325 } 3326 3327 return (rval); 3328 } 3329 3330 /* 3331 * ql_get_adapter_id 3332 * Get adapter ID and topology. 3333 * 3334 * Input: 3335 * ha: adapter state pointer. 3336 * mr: pointer for mailbox data. 3337 * 3338 * Returns: 3339 * ql local function return status code. 3340 * 3341 * Context: 3342 * Kernel context. 3343 */ 3344 int 3345 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3346 { 3347 int rval; 3348 mbx_cmd_t mc = {0}; 3349 mbx_cmd_t *mcp = &mc; 3350 3351 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3352 3353 mcp->mb[0] = MBC_GET_ID; 3354 mcp->out_mb = MBX_0; 3355 if (ha->flags & VP_ENABLED) { 3356 mcp->mb[9] = ha->vp_index; 3357 mcp->out_mb |= MBX_9; 3358 } 3359 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 3360 mcp->timeout = MAILBOX_TOV; 3361 rval = ql_mailbox_command(ha, mcp); 3362 3363 /* Return mailbox data. */ 3364 if (mr != NULL) { 3365 mr->mb[1] = mcp->mb[1]; 3366 mr->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ? 3367 0xffff : mcp->mb[1]); 3368 mr->mb[2] = mcp->mb[2]; 3369 mr->mb[3] = mcp->mb[3]; 3370 mr->mb[6] = mcp->mb[6]; 3371 mr->mb[7] = mcp->mb[7]; 3372 } 3373 3374 if (rval != QL_SUCCESS) { 3375 EL(ha, "failed=%xh\n", rval); 3376 } else { 3377 /*EMPTY*/ 3378 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3379 } 3380 3381 return (rval); 3382 } 3383 3384 /* 3385 * ql_get_fw_version 3386 * Get firmware version. 3387 * 3388 * Input: 3389 * ha: adapter state pointer. 3390 * mr: pointer for mailbox data. 3391 * 3392 * Returns: 3393 * ql local function return status code. 3394 * 3395 * Context: 3396 * Kernel context. 3397 */ 3398 int 3399 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3400 { 3401 int rval; 3402 mbx_cmd_t mc = {0}; 3403 mbx_cmd_t *mcp = &mc; 3404 3405 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3406 3407 mcp->mb[0] = MBC_ABOUT_FIRMWARE; 3408 mcp->out_mb = MBX_0; 3409 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3410 mcp->timeout = MAILBOX_TOV; 3411 rval = ql_mailbox_command(ha, mcp); 3412 3413 /* Return mailbox data. */ 3414 if (mr != NULL) { 3415 mr->mb[1] = mcp->mb[1]; 3416 mr->mb[2] = mcp->mb[2]; 3417 mr->mb[3] = mcp->mb[3]; 3418 mr->mb[4] = mcp->mb[4]; 3419 mr->mb[5] = mcp->mb[5]; 3420 mr->mb[6] = mcp->mb[6]; 3421 } 3422 3423 if (rval != QL_SUCCESS) { 3424 EL(ha, "failed=%xh\n", rval); 3425 } else { 3426 /*EMPTY*/ 3427 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3428 } 3429 3430 return (rval); 3431 } 3432 3433 /* 3434 * ql_data_rate 3435 * Issue data rate Mailbox Command. 3436 * 3437 * Input: 3438 * ha: adapter state pointer. 3439 * mr: pointer for mailbox data. 3440 * 3441 * Returns: 3442 * ql local function return status code. 3443 * 3444 * Context: 3445 * Kernel context. 3446 */ 3447 int 3448 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3449 { 3450 int rval; 3451 mbx_cmd_t mc = {0}; 3452 mbx_cmd_t *mcp = &mc; 3453 3454 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3455 3456 if (mr != NULL) { 3457 mcp->mb[0] = MBC_DATA_RATE; 3458 mcp->mb[1] = mr->mb[1]; 3459 mcp->mb[2] = mr->mb[2]; 3460 mcp->out_mb = MBX_2|MBX_1|MBX_0; 3461 mcp->in_mb = MBX_2|MBX_1|MBX_0; 3462 mcp->timeout = MAILBOX_TOV; 3463 rval = ql_mailbox_command(ha, mcp); 3464 3465 /* Return mailbox data. */ 3466 mr->mb[1] = mcp->mb[1]; 3467 mr->mb[2] = mcp->mb[2]; 3468 } else { 3469 rval = QL_FUNCTION_PARAMETER_ERROR; 3470 } 3471 3472 ha->sfp_stat = mcp->mb[2]; 3473 3474 if (rval != QL_SUCCESS) { 3475 EL(ha, "failed=%xh\n", rval); 3476 } else { 3477 /*EMPTY*/ 3478 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3479 } 3480 3481 return (rval); 3482 } 3483 3484 /* 3485 * ql_Diag_Loopback 3486 * Issue Reset Link Status mailbox command 3487 * 3488 * Input: 3489 * ha: adapter state pointer. 3490 * bp: buffer pointer. 3491 * size: buffer size. 3492 * opt: command options. 3493 * it_cnt: iteration count. 3494 * mr: pointer for mailbox data. 3495 * 3496 * Returns: 3497 * ql local function return status code. 3498 * 3499 * Context: 3500 * Kernel context. 3501 */ 3502 int 3503 ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, 3504 uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr) 3505 { 3506 int rval; 3507 dma_mem_t mem_desc; 3508 mbx_cmd_t mc = {0}; 3509 mbx_cmd_t *mcp = &mc; 3510 3511 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3512 3513 3514 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3515 QL_SUCCESS) { 3516 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3517 return (rval); 3518 } 3519 3520 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 3521 mcp->mb[1] = opt; 3522 mcp->mb[2] = 0; 3523 mcp->mb[3] = 0; 3524 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3525 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3526 mcp->mb[10] = LSW(size); 3527 mcp->mb[11] = MSW(size); 3528 mcp->mb[12] = 0; 3529 mcp->mb[13] = 0; 3530 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3531 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3532 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3533 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3534 mcp->mb[18] = LSW(it_cnt); 3535 mcp->mb[19] = MSW(it_cnt); 3536 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3537 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3538 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 3539 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 3540 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 3541 mcp->timeout = it_cnt / 300; 3542 if (mcp->timeout < MAILBOX_TOV) { 3543 mcp->timeout = MAILBOX_TOV; 3544 } 3545 rval = ql_mailbox_command(ha, mcp); 3546 3547 if (rval == QL_SUCCESS) { 3548 ql_get_mbox_dma_data(&mem_desc, bp); 3549 } 3550 3551 ql_free_dma_resource(ha, &mem_desc); 3552 3553 /* Return mailbox data. */ 3554 if (mr != NULL) { 3555 mr->mb[0] = mcp->mb[0]; 3556 mr->mb[1] = mcp->mb[1]; 3557 mr->mb[2] = mcp->mb[2]; 3558 mr->mb[3] = mcp->mb[3]; 3559 mr->mb[18] = mcp->mb[18]; 3560 mr->mb[19] = mcp->mb[19]; 3561 } 3562 3563 if (rval != QL_SUCCESS) { 3564 EL(ha, "failed=%xh, mb1=%xh\n", rval, 3565 mcp->mb[1]); 3566 } else { 3567 /*EMPTY*/ 3568 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3569 } 3570 3571 return (rval); 3572 } 3573 3574 /* 3575 * ql_diag_echo 3576 * Issue Diag echo mailbox command. Valid for qla23xx HBA's. 3577 * 3578 * Input: 3579 * ha: adapter state pointer. 3580 * bp: buffer pointer. 3581 * size: buffer size. 3582 * opt: command options. 3583 * mr: pointer to mailbox status. 3584 * 3585 * Returns: 3586 * ql local function return status code. 3587 * 3588 * Context: 3589 * Kernel context. 3590 */ 3591 int 3592 ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt, 3593 ql_mbx_data_t *mr) 3594 { 3595 int rval; 3596 dma_mem_t mem_desc; 3597 mbx_cmd_t mc = {0}; 3598 mbx_cmd_t *mcp = &mc; 3599 3600 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3601 3602 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3603 QL_SUCCESS) { 3604 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3605 return (rval); 3606 } 3607 3608 mcp->mb[0] = MBC_ECHO; 3609 mcp->mb[1] = opt; 3610 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3611 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3612 mcp->mb[10] = LSW(size); 3613 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3614 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3615 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3616 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3617 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3618 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3619 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| 3620 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 3621 mcp->in_mb = MBX_1|MBX_0; 3622 mcp->timeout = MAILBOX_TOV; 3623 rval = ql_mailbox_command(ha, mcp); 3624 3625 if (rval == QL_SUCCESS) { 3626 ql_get_mbox_dma_data(&mem_desc, bp); 3627 } 3628 3629 ql_free_dma_resource(ha, &mem_desc); 3630 3631 if (mr != NULL) { 3632 mr->mb[0] = mcp->mb[0]; 3633 } 3634 3635 if (rval != QL_SUCCESS) { 3636 EL(ha, "failed=%xh, mb1=%xh\n", rval, 3637 mcp->mb[1]); 3638 } else { 3639 /*EMPTY*/ 3640 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3641 } 3642 3643 return (rval); 3644 } 3645 3646 /* 3647 * ql_serdes_param 3648 * Set/Get serdes transmit parameters mailbox command. 3649 * 3650 * Input: 3651 * ha: adapter state pointer. 3652 * mr: pointer to mailbox in/out parameters. 3653 * 3654 * Returns: 3655 * ql local function return status code. 3656 * 3657 * Context: 3658 * Kernel context. 3659 */ 3660 int 3661 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3662 { 3663 int rval; 3664 mbx_cmd_t mc = {0}; 3665 mbx_cmd_t *mcp = &mc; 3666 3667 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3668 3669 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS; 3670 mcp->mb[1] = mr->mb[1]; 3671 mcp->mb[2] = mr->mb[2]; 3672 mcp->mb[3] = mr->mb[3]; 3673 mcp->mb[4] = mr->mb[4]; 3674 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3675 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0; 3676 mcp->timeout = MAILBOX_TOV; 3677 rval = ql_mailbox_command(ha, mcp); 3678 3679 /* Return mailbox data. */ 3680 if (mr != NULL) { 3681 mr->mb[0] = mcp->mb[0]; 3682 mr->mb[2] = mcp->mb[2]; 3683 mr->mb[3] = mcp->mb[3]; 3684 mr->mb[4] = mcp->mb[4]; 3685 } 3686 3687 if (rval != QL_SUCCESS) { 3688 EL(ha, "failed=%xh\n", rval); 3689 } else { 3690 /*EMPTY*/ 3691 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3692 } 3693 3694 return (rval); 3695 } 3696 3697 /* 3698 * ql_get_timeout_parameters 3699 * Issue get timeout parameters mailbox command. 3700 * 3701 * Input: 3702 * ha: adapter state pointer. 3703 * mr: pointer to mailbox in/out parameters. 3704 * 3705 * Returns: 3706 * ql local function return status code. 3707 * 3708 * Context: 3709 * Kernel context. 3710 */ 3711 int 3712 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov) 3713 { 3714 int rval; 3715 mbx_cmd_t mc = {0}; 3716 mbx_cmd_t *mcp = &mc; 3717 3718 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3719 3720 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS; 3721 mcp->out_mb = MBX_0; 3722 mcp->in_mb = MBX_3|MBX_0; 3723 mcp->timeout = MAILBOX_TOV; 3724 rval = ql_mailbox_command(ha, mcp); 3725 if (rval == QL_SUCCESS) { 3726 /* Get 2 * R_A_TOV in seconds */ 3727 if (CFG_IST(ha, CFG_CTRL_2200) || mcp->mb[3] == 0) { 3728 *tov = R_A_TOV_DEFAULT; 3729 } else { 3730 *tov = (uint16_t)(mcp->mb[3] / 10); 3731 if (mcp->mb[3] % 10 != 0) { 3732 *tov = (uint16_t)(*tov + 1); 3733 } 3734 /* 3735 * Adjust value to prevent driver timeout at the same 3736 * time as device. 3737 */ 3738 *tov = (uint16_t)(*tov + 5); 3739 } 3740 } else { 3741 *tov = R_A_TOV_DEFAULT; 3742 } 3743 3744 if (rval != QL_SUCCESS) { 3745 EL(ha, "failed=%xh\n", rval); 3746 } else { 3747 /*EMPTY*/ 3748 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3749 } 3750 3751 return (rval); 3752 } 3753 3754 /* 3755 * ql_stop_firmware 3756 * Issue stop firmware Mailbox Command. 3757 * 3758 * Input: 3759 * ha: adapter state pointer. 3760 * 3761 * Returns: 3762 * ql local function return status code. 3763 * 3764 * Context: 3765 * Kernel context. 3766 */ 3767 int 3768 ql_stop_firmware(ql_adapter_state_t *ha) 3769 { 3770 int rval; 3771 mbx_cmd_t mc = {0}; 3772 mbx_cmd_t *mcp = &mc; 3773 3774 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3775 3776 mcp->mb[0] = MBC_STOP_FIRMWARE; 3777 mcp->out_mb = MBX_0; 3778 mcp->in_mb = MBX_0; 3779 mcp->timeout = MAILBOX_TOV; 3780 rval = ql_mailbox_command(ha, mcp); 3781 3782 if (rval != QL_SUCCESS) { 3783 EL(ha, "failed=%xh\n", rval); 3784 } else { 3785 /*EMPTY*/ 3786 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3787 } 3788 3789 return (rval); 3790 } 3791 3792 /* 3793 * ql_read_sfp 3794 * Issue Read SFP Mailbox command 3795 * 3796 * Input: 3797 * ha: adapter state pointer. 3798 * mem: pointer to dma memory object for command. 3799 * dev: Device address (A0h or A2h). 3800 * addr: Data address on SFP EEPROM (0�255). 3801 * 3802 * Returns: 3803 * ql local function return status code. 3804 * 3805 * Context: 3806 * Kernel context. 3807 */ 3808 int 3809 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev, 3810 uint16_t addr) 3811 { 3812 int rval; 3813 mbx_cmd_t mc = {0}; 3814 mbx_cmd_t *mcp = &mc; 3815 3816 QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance); 3817 3818 mcp->mb[0] = MBC_READ_SFP; 3819 mcp->mb[1] = dev; 3820 mcp->mb[2] = MSW(mem->cookies->dmac_address); 3821 mcp->mb[3] = LSW(mem->cookies->dmac_address); 3822 mcp->mb[6] = MSW(mem->cookies->dmac_notused); 3823 mcp->mb[7] = LSW(mem->cookies->dmac_notused); 3824 mcp->mb[8] = LSW(mem->size); 3825 mcp->mb[9] = addr; 3826 mcp->mb[10] = 0; 3827 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 3828 mcp->in_mb = MBX_1|MBX_0; 3829 mcp->timeout = MAILBOX_TOV; 3830 rval = ql_mailbox_command(ha, mcp); 3831 3832 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size, 3833 DDI_DMA_SYNC_FORKERNEL); 3834 3835 if (rval != QL_SUCCESS) { 3836 EL(ha, "failed=%xh\n", rval); 3837 } else { 3838 /*EMPTY*/ 3839 QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance); 3840 } 3841 3842 return (rval); 3843 } 3844 3845 /* 3846 * ql_iidma_rate 3847 * Issue get/set iidma rate command 3848 * 3849 * Input: 3850 * ha: adapter state pointer. 3851 * loop_id: n-port handle to set/get iidma rate. 3852 * idma_rate: Pointer to iidma rate. 3853 * option: iidma firmware option (set or get data). 3854 * 0 --> Get iidma rate 3855 * 1 --> Set iidma rate 3856 * 3857 * Returns: 3858 * ql local function return status code. 3859 * 3860 * Context: 3861 * Kernel context. 3862 */ 3863 int 3864 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate, 3865 uint32_t option) 3866 { 3867 int rval; 3868 mbx_cmd_t mc = {0}; 3869 mbx_cmd_t *mcp = &mc; 3870 3871 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3872 3873 mcp->mb[0] = MBC_PORT_PARAM; 3874 mcp->mb[1] = loop_id; 3875 mcp->mb[2] = (uint16_t)option; 3876 mcp->out_mb = MBX_0|MBX_1|MBX_2; 3877 mcp->in_mb = MBX_0|MBX_1; 3878 3879 if (option & BIT_0) { 3880 mcp->mb[3] = (uint16_t)*idma_rate; 3881 mcp->out_mb |= MBX_3; 3882 } else { 3883 mcp->in_mb |= MBX_3; 3884 } 3885 3886 mcp->timeout = MAILBOX_TOV; 3887 rval = ql_mailbox_command(ha, mcp); 3888 3889 if (rval != QL_SUCCESS) { 3890 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]); 3891 } else { 3892 if (option == 0) { 3893 *idma_rate = mcp->mb[3]; 3894 } 3895 3896 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3897 } 3898 3899 return (rval); 3900 } 3901 3902 /* 3903 * ql_set_xmit_parms 3904 * Set transmit parameters 3905 * 3906 * Input: 3907 * ha: adapter state pointer. 3908 * 3909 * Returns: 3910 * ql local function return status code. 3911 * 3912 * Context: 3913 * Kernel context. 3914 */ 3915 int 3916 ql_set_xmit_parms(ql_adapter_state_t *ha) 3917 { 3918 int rval; 3919 mbx_cmd_t mc = {0}; 3920 mbx_cmd_t *mcp = &mc; 3921 3922 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3923 3924 mcp->mb[0] = MBC_XMIT_PARM; 3925 mcp->mb[1] = BIT_1; 3926 mcp->out_mb = MBX_1|MBX_0; 3927 mcp->in_mb = MBX_0; 3928 mcp->timeout = MAILBOX_TOV; 3929 rval = ql_mailbox_command(ha, mcp); 3930 3931 if (rval != QL_SUCCESS) { 3932 EL(ha, "failed=%xh\n", rval); 3933 } else { 3934 /*EMPTY*/ 3935 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3936 } 3937 return (rval); 3938 } 3939 3940 /* 3941 * ql_fw_etrace 3942 * Firmware extended tracing. 3943 * 3944 * Input: 3945 * ha: adapter state pointer. 3946 * mem: pointer to dma memory object for command. 3947 * opt: options. 3948 * FTO_EXTENABLE 3949 * FTO_EXTDISABLE 3950 * FTO_FCEENABLE 3951 * FTO_FCEDISABLE 3952 * 3953 * Returns: 3954 * ql local function return status code. 3955 * 3956 * Context: 3957 * Kernel context. 3958 */ 3959 int 3960 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt) 3961 { 3962 int rval = QL_SUCCESS; 3963 mbx_cmd_t mc = {0}; 3964 mbx_cmd_t *mcp = &mc; 3965 3966 QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance); 3967 3968 mcp->mb[0] = MBC_TRACE_CONTROL; 3969 mcp->mb[1] = opt; 3970 mcp->out_mb = MBX_1|MBX_0; 3971 mcp->in_mb = MBX_0; 3972 mcp->timeout = MAILBOX_TOV; 3973 3974 switch (opt) { 3975 case FTO_FCEENABLE: 3976 case FTO_EXTENABLE: 3977 mcp->mb[2] = LSW(mem->cookies->dmac_address); 3978 mcp->mb[3] = MSW(mem->cookies->dmac_address); 3979 mcp->mb[4] = LSW(mem->cookies->dmac_notused); 3980 mcp->mb[5] = MSW(mem->cookies->dmac_notused); 3981 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */ 3982 mcp->mb[7] = 0; 3983 mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2; 3984 if (opt == FTO_FCEENABLE) { 3985 mcp->mb[8] = (uint16_t)ha->fwfcetraceopt; 3986 mcp->mb[9] = FTO_FCEMAXTRACEBUF; 3987 mcp->mb[10] = FTO_FCEMAXTRACEBUF; 3988 mcp->out_mb |= MBX_10|MBX_9|MBX_8; 3989 } 3990 break; 3991 3992 case FTO_FCEDISABLE: 3993 mcp->mb[2] = BIT_0; 3994 mcp->out_mb = MBX_2; 3995 break; 3996 3997 case FTO_EXTDISABLE: 3998 break; 3999 4000 default: 4001 EL(ha, "invalid option: %xh\n", opt); 4002 rval = QL_PARAMETER_ERROR; 4003 break; 4004 } 4005 4006 if (rval == QL_SUCCESS) { 4007 rval = ql_mailbox_command(ha, mcp); 4008 } 4009 4010 if (rval != QL_SUCCESS) { 4011 EL(ha, "failed=%xh\n", rval); 4012 } else { 4013 /*EMPTY*/ 4014 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4015 } 4016 4017 return (rval); 4018 } 4019 4020 /* 4021 * ql_reset_menlo 4022 * Reset Menlo Mailbox Command. 4023 * 4024 * Input: 4025 * ha: adapter state pointer. 4026 * mr: pointer to mailbox in/out parameters. 4027 * opt: options. 4028 * 4029 * Returns: 4030 * ql local function return status code. 4031 * 4032 * Context: 4033 * Kernel context. 4034 */ 4035 int 4036 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt) 4037 { 4038 int rval; 4039 mbx_cmd_t mc = {0}; 4040 mbx_cmd_t *mcp = &mc; 4041 4042 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4043 4044 mcp->mb[0] = MBC_RESET_MENLO; 4045 mcp->mb[1] = opt; 4046 mcp->out_mb = MBX_1|MBX_0; 4047 mcp->in_mb = MBX_1|MBX_0; 4048 mcp->timeout = MAILBOX_TOV; 4049 rval = ql_mailbox_command(ha, mcp); 4050 4051 /* Return mailbox data. */ 4052 if (mr != NULL) { 4053 mr->mb[0] = mcp->mb[0]; 4054 mr->mb[1] = mcp->mb[1]; 4055 } 4056 4057 if (rval != QL_SUCCESS) { 4058 EL(ha, "failed=%xh\n", rval); 4059 } else { 4060 /*EMPTY*/ 4061 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4062 } 4063 4064 return (rval); 4065 } 4066