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