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_242581) ? 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_2581)) || 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 * findex: FCF index. 574 * lb: loop back parameter structure pointer. 575 * 576 * Returns: 577 * ql local function return status code. 578 * 579 * Context: 580 * Kernel context. 581 */ 582 #ifndef apps_64bit 583 int 584 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb, 585 uint32_t h_xmit, uint32_t h_rcv) 586 { 587 int rval; 588 mbx_cmd_t mc = {0}; 589 mbx_cmd_t *mcp = &mc; 590 591 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 592 593 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 594 mcp->mb[1] = lb->options; 595 mcp->mb[2] = findex; 596 mcp->mb[6] = LSW(h_rcv); 597 mcp->mb[7] = MSW(h_rcv); 598 mcp->mb[10] = LSW(lb->transfer_count); 599 mcp->mb[11] = MSW(lb->transfer_count); 600 mcp->mb[12] = lb->transfer_segment_count; 601 mcp->mb[13] = lb->receive_segment_count; 602 mcp->mb[14] = LSW(lb->transfer_data_address); 603 mcp->mb[15] = MSW(lb->transfer_data_address); 604 mcp->mb[16] = LSW(lb->receive_data_address); 605 mcp->mb[17] = MSW(lb->receive_data_address); 606 mcp->mb[18] = LSW(lb->iteration_count); 607 mcp->mb[19] = MSW(lb->iteration_count); 608 mcp->mb[20] = LSW(h_xmit); 609 mcp->mb[21] = MSW(h_xmit); 610 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 611 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 612 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 613 mcp->timeout = lb->iteration_count / 300; 614 615 if (mcp->timeout < MAILBOX_TOV) { 616 mcp->timeout = MAILBOX_TOV; 617 } 618 619 rval = ql_mailbox_command(ha, mcp); 620 621 if (rval != QL_SUCCESS) { 622 EL(ha, "failed, rval = %xh\n", rval); 623 } else { 624 /*EMPTY*/ 625 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 626 } 627 628 return (rval); 629 } 630 #else 631 int 632 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb) 633 { 634 int rval; 635 mbx_cmd_t mc = {0}; 636 mbx_cmd_t *mcp = &mc; 637 638 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 639 640 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 641 mcp->mb[1] = lb->options; 642 mcp->mb[2] = findex; 643 mcp->mb[6] = LSW(h_rcv); 644 mcp->mb[7] = MSW(h_rcv); 645 mcp->mb[6] = LSW(MSD(lb->receive_data_address)); 646 mcp->mb[7] = MSW(MSD(lb->receive_data_address)); 647 mcp->mb[10] = LSW(lb->transfer_count); 648 mcp->mb[11] = MSW(lb->transfer_count); 649 mcp->mb[12] = lb->transfer_segment_count; 650 mcp->mb[13] = lb->receive_segment_count; 651 mcp->mb[14] = LSW(lb->transfer_data_address); 652 mcp->mb[15] = MSW(lb->transfer_data_address); 653 mcp->mb[14] = LSW(LSD(lb->transfer_data_address)); 654 mcp->mb[15] = MSW(LSD(lb->transfer_data_address)); 655 mcp->mb[16] = LSW(lb->receive_data_address); 656 mcp->mb[17] = MSW(lb->receive_data_address); 657 mcp->mb[16] = LSW(LSD(lb->receive_data_address)); 658 mcp->mb[17] = MSW(LSD(lb->receive_data_address)); 659 mcp->mb[18] = LSW(lb->iteration_count); 660 mcp->mb[19] = MSW(lb->iteration_count); 661 mcp->mb[20] = LSW(h_xmit); 662 mcp->mb[21] = MSW(h_xmit); 663 mcp->mb[20] = LSW(MSD(lb->transfer_data_address)); 664 mcp->mb[21] = MSW(MSD(lb->transfer_data_address)); 665 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 666 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 667 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 668 mcp->timeout = lb->iteration_count / 300; 669 670 if (mcp->timeout < MAILBOX_TOV) { 671 mcp->timeout = MAILBOX_TOV; 672 } 673 674 rval = ql_mailbox_command(ha, mcp); 675 676 if (rval != QL_SUCCESS) { 677 EL(ha, "failed, rval = %xh\n", rval); 678 } else { 679 /*EMPTY*/ 680 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 681 } 682 return (rval); 683 } 684 #endif 685 686 /* 687 * ql_echo 688 * Issue an ELS echo using the user specified data to a user specified 689 * destination 690 * 691 * Input: 692 * ha: adapter state pointer. 693 * findex: FCF index. 694 * echo_pt: echo parameter structure pointer. 695 * 696 * Returns: 697 * ql local function return status code. 698 * 699 * Context: 700 * Kernel context. 701 */ 702 int 703 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt) 704 { 705 int rval; 706 mbx_cmd_t mc = {0}; 707 mbx_cmd_t *mcp = &mc; 708 709 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 710 711 mcp->mb[0] = MBC_ECHO; /* ECHO command */ 712 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */ 713 /* addressing (bit 6) and */ 714 /* real echo (bit 15 */ 715 mcp->mb[2] = findex; 716 717 /* 718 * I know this looks strange, using a field labled "not used" 719 * The way the ddi_dma_cookie_t structure/union is defined 720 * is a union of one 64 bit entity with an array of two 32 721 * bit enititys. Since we have routines to convert 32 bit 722 * entities into 16 bit entities it is easier to use 723 * both 32 bit union members then the one 64 bit union 724 * member 725 */ 726 if (echo_pt->options & BIT_6) { 727 /* 64 bit addressing */ 728 /* Receive data dest add in system memory bits 47-32 */ 729 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused); 730 731 /* Receive data dest add in system memory bits 63-48 */ 732 mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused); 733 734 /* Transmit data source address in system memory bits 47-32 */ 735 mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused); 736 737 /* Transmit data source address in system memory bits 63-48 */ 738 mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused); 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_2|MBX_1|MBX_0; 758 mcp->in_mb = MBX_3|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_242581)) { 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_242581)) { 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 * ql 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_242581)) { 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_242581)) { 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->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1107 mcp->in_mb = MBX_0; 1108 mcp->timeout = MAILBOX_TOV; 1109 rval = ql_mailbox_command(ha, mcp); 1110 } 1111 1112 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1113 1114 if (rval != QL_SUCCESS) { 1115 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1116 } else { 1117 /*EMPTY*/ 1118 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1119 } 1120 return (rval); 1121 } 1122 1123 /* 1124 * ql_clear_task_set 1125 * Issue clear task set mailbox command. 1126 * 1127 * Input: 1128 * ha: adapter state pointer. 1129 * tq: target queue pointer. 1130 * lun: LUN. 1131 * 1132 * Returns: 1133 * ql local function return status code. 1134 * 1135 * Context: 1136 * Kernel context. 1137 */ 1138 int 1139 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1140 { 1141 int rval; 1142 mbx_cmd_t mc = {0}; 1143 mbx_cmd_t *mcp = &mc; 1144 1145 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1146 1147 if (CFG_IST(ha, CFG_CTRL_242581)) { 1148 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0); 1149 } else { 1150 mcp->mb[0] = MBC_CLEAR_TASK_SET; 1151 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1152 mcp->mb[1] = tq->loop_id; 1153 } else { 1154 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1155 } 1156 mcp->mb[2] = lun; 1157 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1158 mcp->in_mb = MBX_0; 1159 mcp->timeout = MAILBOX_TOV; 1160 rval = ql_mailbox_command(ha, mcp); 1161 } 1162 1163 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1164 1165 if (rval != QL_SUCCESS) { 1166 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1167 } else { 1168 /*EMPTY*/ 1169 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1170 } 1171 1172 return (rval); 1173 } 1174 1175 /* 1176 * ql_abort_task_set 1177 * Issue abort task set mailbox command. 1178 * 1179 * Input: 1180 * ha: adapter state pointer. 1181 * tq: target queue pointer. 1182 * lun: LUN. 1183 * 1184 * Returns: 1185 * ql local function return status code. 1186 * 1187 * Context: 1188 * Kernel context. 1189 */ 1190 int 1191 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 1192 { 1193 int rval; 1194 mbx_cmd_t mc = {0}; 1195 mbx_cmd_t *mcp = &mc; 1196 1197 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1198 1199 if (CFG_IST(ha, CFG_CTRL_242581)) { 1200 rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0); 1201 } else { 1202 mcp->mb[0] = MBC_ABORT_TASK_SET; 1203 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1204 mcp->mb[1] = tq->loop_id; 1205 } else { 1206 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1207 } 1208 mcp->mb[2] = lun; 1209 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1210 mcp->in_mb = MBX_0; 1211 mcp->timeout = MAILBOX_TOV; 1212 rval = ql_mailbox_command(ha, mcp); 1213 } 1214 1215 (void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID); 1216 1217 if (rval != QL_SUCCESS) { 1218 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1219 } else { 1220 /*EMPTY*/ 1221 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1222 } 1223 1224 return (rval); 1225 } 1226 1227 /* 1228 * ql_task_mgmt_iocb 1229 * Function issues task management IOCB. 1230 * 1231 * Input: 1232 * ha: adapter state pointer. 1233 * tq: target queue pointer. 1234 * lun: LUN. 1235 * flags: control flags. 1236 * delay: seconds. 1237 * 1238 * Returns: 1239 * ql local function return status code. 1240 * 1241 * Context: 1242 * Kernel context 1243 */ 1244 static int 1245 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun, 1246 uint32_t flags, uint16_t delay) 1247 { 1248 ql_mbx_iocb_t *pkt; 1249 int rval; 1250 uint32_t pkt_size; 1251 1252 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1253 1254 pkt_size = sizeof (ql_mbx_iocb_t); 1255 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1256 if (pkt == NULL) { 1257 EL(ha, "failed, kmem_zalloc\n"); 1258 return (QL_MEMORY_ALLOC_FAILED); 1259 } 1260 1261 pkt->mgmt.entry_type = TASK_MGMT_TYPE; 1262 pkt->mgmt.entry_count = 1; 1263 1264 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 1265 pkt->mgmt.delay = (uint16_t)LE_16(delay); 1266 pkt->mgmt.timeout = LE_16(MAILBOX_TOV); 1267 pkt->mgmt.fcp_lun[2] = LSB(lun); 1268 pkt->mgmt.fcp_lun[3] = MSB(lun); 1269 pkt->mgmt.control_flags = LE_32(flags); 1270 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa; 1271 pkt->mgmt.target_id[1] = tq->d_id.b.area; 1272 pkt->mgmt.target_id[2] = tq->d_id.b.domain; 1273 pkt->mgmt.vp_index = ha->vp_index; 1274 1275 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1276 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) { 1277 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1278 pkt->sts24.entry_status, tq->d_id.b24); 1279 rval = QL_FUNCTION_PARAMETER_ERROR; 1280 } 1281 1282 LITTLE_ENDIAN_16(&pkt->sts24.comp_status); 1283 1284 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) { 1285 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 1286 pkt->sts24.comp_status, tq->d_id.b24); 1287 rval = QL_FUNCTION_FAILED; 1288 } 1289 1290 kmem_free(pkt, pkt_size); 1291 1292 if (rval != QL_SUCCESS) { 1293 EL(ha, "failed, rval = %xh\n", rval); 1294 } else { 1295 /*EMPTY*/ 1296 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1297 } 1298 1299 return (rval); 1300 } 1301 1302 /* 1303 * ql_loop_port_bypass 1304 * Issue loop port bypass mailbox command. 1305 * 1306 * Input: 1307 * ha: adapter state pointer. 1308 * tq: target queue pointer. 1309 * 1310 * Returns: 1311 * ql local function return status code. 1312 * 1313 * Context: 1314 * Kernel context. 1315 */ 1316 int 1317 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq) 1318 { 1319 int rval; 1320 mbx_cmd_t mc = {0}; 1321 mbx_cmd_t *mcp = &mc; 1322 1323 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1324 1325 mcp->mb[0] = MBC_LOOP_PORT_BYPASS; 1326 1327 if (CFG_IST(ha, CFG_CTRL_242581)) { 1328 mcp->mb[1] = tq->d_id.b.al_pa; 1329 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1330 mcp->mb[1] = tq->loop_id; 1331 } else { 1332 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1333 } 1334 1335 mcp->out_mb = MBX_1|MBX_0; 1336 mcp->in_mb = MBX_0; 1337 mcp->timeout = MAILBOX_TOV; 1338 rval = ql_mailbox_command(ha, mcp); 1339 1340 if (rval != QL_SUCCESS) { 1341 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1342 } else { 1343 /*EMPTY*/ 1344 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1345 } 1346 1347 return (rval); 1348 } 1349 1350 /* 1351 * ql_loop_port_enable 1352 * Issue loop port enable mailbox command. 1353 * 1354 * Input: 1355 * ha: adapter state pointer. 1356 * tq: target queue pointer. 1357 * 1358 * Returns: 1359 * ql local function return status code. 1360 * 1361 * Context: 1362 * Kernel context. 1363 */ 1364 int 1365 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq) 1366 { 1367 int rval; 1368 mbx_cmd_t mc = {0}; 1369 mbx_cmd_t *mcp = &mc; 1370 1371 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1372 1373 mcp->mb[0] = MBC_LOOP_PORT_ENABLE; 1374 1375 if (CFG_IST(ha, CFG_CTRL_242581)) { 1376 mcp->mb[1] = tq->d_id.b.al_pa; 1377 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1378 mcp->mb[1] = tq->loop_id; 1379 } else { 1380 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1381 } 1382 mcp->out_mb = MBX_1|MBX_0; 1383 mcp->in_mb = MBX_0; 1384 mcp->timeout = MAILBOX_TOV; 1385 rval = ql_mailbox_command(ha, mcp); 1386 1387 if (rval != QL_SUCCESS) { 1388 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1389 } else { 1390 /*EMPTY*/ 1391 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1392 } 1393 1394 return (rval); 1395 } 1396 1397 /* 1398 * ql_login_lport 1399 * Issue login loop port mailbox command. 1400 * 1401 * Input: 1402 * ha: adapter state pointer. 1403 * tq: target queue pointer. 1404 * loop_id: FC loop id. 1405 * opt: options. 1406 * LLF_NONE, LLF_PLOGI 1407 * 1408 * Returns: 1409 * ql local function return status code. 1410 * 1411 * Context: 1412 * Kernel context. 1413 */ 1414 int 1415 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1416 uint16_t opt) 1417 { 1418 int rval; 1419 uint16_t flags; 1420 ql_mbx_data_t mr; 1421 mbx_cmd_t mc = {0}; 1422 mbx_cmd_t *mcp = &mc; 1423 1424 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1425 ha->instance, tq->d_id.b24, loop_id); 1426 1427 if (CFG_IST(ha, CFG_CTRL_242581)) { 1428 flags = CF_CMD_PLOGI; 1429 if ((opt & LLF_PLOGI) == 0) { 1430 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1431 } 1432 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr); 1433 } else { 1434 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 1435 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1436 mcp->mb[1] = loop_id; 1437 } else { 1438 mcp->mb[1] = (uint16_t)(loop_id << 8); 1439 } 1440 mcp->mb[2] = opt; 1441 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1442 mcp->in_mb = MBX_0; 1443 mcp->timeout = MAILBOX_TOV; 1444 rval = ql_mailbox_command(ha, mcp); 1445 } 1446 1447 if (rval != QL_SUCCESS) { 1448 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1449 loop_id, rval); 1450 } else { 1451 /*EMPTY*/ 1452 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1453 } 1454 1455 return (rval); 1456 } 1457 1458 /* 1459 * ql_login_fport 1460 * Issue login fabric port mailbox command. 1461 * 1462 * Input: 1463 * ha: adapter state pointer. 1464 * tq: target queue pointer. 1465 * loop_id: FC loop id. 1466 * opt: options. 1467 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI 1468 * mr: pointer for mailbox data. 1469 * 1470 * Returns: 1471 * ql local function return status code. 1472 * 1473 * Context: 1474 * Kernel context. 1475 */ 1476 int 1477 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1478 uint16_t opt, ql_mbx_data_t *mr) 1479 { 1480 int rval; 1481 uint16_t flags; 1482 mbx_cmd_t mc = {0}; 1483 mbx_cmd_t *mcp = &mc; 1484 1485 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 1486 ha->instance, tq->d_id.b24, loop_id); 1487 1488 if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) { 1489 opt = (uint16_t)(opt | LFF_NO_PRLI); 1490 } 1491 1492 if (CFG_IST(ha, CFG_CTRL_242581)) { 1493 flags = CF_CMD_PLOGI; 1494 if (opt & LFF_NO_PLOGI) { 1495 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1496 } 1497 if (opt & LFF_NO_PRLI) { 1498 flags = (uint16_t)(flags | CFO_SKIP_PRLI); 1499 } 1500 rval = ql_log_iocb(ha, tq, loop_id, flags, mr); 1501 } else { 1502 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1503 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1504 mcp->mb[1] = loop_id; 1505 mcp->mb[10] = opt; 1506 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 1507 } else { 1508 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 1509 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1510 } 1511 mcp->mb[2] = MSW(tq->d_id.b24); 1512 mcp->mb[3] = LSW(tq->d_id.b24); 1513 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 1514 mcp->timeout = MAILBOX_TOV; 1515 rval = ql_mailbox_command(ha, mcp); 1516 1517 /* Return mailbox data. */ 1518 if (mr != NULL) { 1519 mr->mb[0] = mcp->mb[0]; 1520 mr->mb[1] = mcp->mb[1]; 1521 mr->mb[2] = mcp->mb[2]; 1522 mr->mb[6] = mcp->mb[6]; 1523 mr->mb[7] = mcp->mb[7]; 1524 } 1525 } 1526 1527 if (rval != QL_SUCCESS) { 1528 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, " 1529 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1], 1530 mr->mb[2]); 1531 } else { 1532 /*EMPTY*/ 1533 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1534 } 1535 1536 return (rval); 1537 } 1538 1539 /* 1540 * ql_logout_fabric_port 1541 * Issue logout fabric port mailbox command. 1542 * 1543 * Input: 1544 * ha: adapter state pointer. 1545 * tq: target queue pointer. 1546 * 1547 * Returns: 1548 * ql local function return status code. 1549 * 1550 * Context: 1551 * Kernel context. 1552 */ 1553 int 1554 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq) 1555 { 1556 int rval; 1557 uint16_t flag; 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, loop_id=%xh d_id=%xh\n", 1563 ha->instance, tq->loop_id, tq->d_id.b24); 1564 1565 if (CFG_IST(ha, CFG_CTRL_242581)) { 1566 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1567 CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE : 1568 CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE); 1569 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr); 1570 } else { 1571 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0); 1572 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 1573 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1574 mcp->mb[1] = tq->loop_id; 1575 mcp->mb[10] = flag; 1576 mcp->out_mb = MBX_10|MBX_1|MBX_0; 1577 } else { 1578 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag); 1579 mcp->out_mb = MBX_1|MBX_0; 1580 } 1581 mcp->in_mb = MBX_0; 1582 mcp->timeout = MAILBOX_TOV; 1583 rval = ql_mailbox_command(ha, mcp); 1584 } 1585 1586 if (rval != QL_SUCCESS) { 1587 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval, 1588 tq->d_id.b24, tq->loop_id); 1589 } else { 1590 /*EMPTY*/ 1591 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1592 } 1593 1594 return (rval); 1595 } 1596 1597 /* 1598 * ql_log_iocb 1599 * Function issues login/logout IOCB. 1600 * 1601 * Input: 1602 * ha: adapter state pointer. 1603 * tq: target queue pointer. 1604 * loop_id: FC Loop ID. 1605 * flags: control flags. 1606 * mr: pointer for mailbox data. 1607 * 1608 * Returns: 1609 * ql local function return status code. 1610 * 1611 * Context: 1612 * Kernel context. 1613 */ 1614 int 1615 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1616 uint16_t flags, ql_mbx_data_t *mr) 1617 { 1618 ql_mbx_iocb_t *pkt; 1619 int rval; 1620 uint32_t pkt_size; 1621 1622 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1623 1624 pkt_size = sizeof (ql_mbx_iocb_t); 1625 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1626 if (pkt == NULL) { 1627 EL(ha, "failed, kmem_zalloc\n"); 1628 return (QL_MEMORY_ALLOC_FAILED); 1629 } 1630 1631 pkt->log.entry_type = LOG_TYPE; 1632 pkt->log.entry_count = 1; 1633 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id); 1634 pkt->log.control_flags = (uint16_t)LE_16(flags); 1635 pkt->log.port_id[0] = tq->d_id.b.al_pa; 1636 pkt->log.port_id[1] = tq->d_id.b.area; 1637 pkt->log.port_id[2] = tq->d_id.b.domain; 1638 pkt->log.vp_index = ha->vp_index; 1639 1640 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1641 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) { 1642 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1643 pkt->log.entry_status, tq->d_id.b24); 1644 rval = QL_FUNCTION_PARAMETER_ERROR; 1645 } 1646 1647 if (rval == QL_SUCCESS) { 1648 if (pkt->log.rsp_size == 0xB) { 1649 LITTLE_ENDIAN_32(&pkt->log.io_param[5]); 1650 tq->cmn_features = MSW(pkt->log.io_param[5]); 1651 LITTLE_ENDIAN_32(&pkt->log.io_param[6]); 1652 tq->conc_sequences = MSW(pkt->log.io_param[6]); 1653 tq->relative_offset = LSW(pkt->log.io_param[6]); 1654 LITTLE_ENDIAN_32(&pkt->log.io_param[9]); 1655 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]); 1656 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]); 1657 LITTLE_ENDIAN_32(&pkt->log.io_param[10]); 1658 tq->class3_open_sequences_per_exch = 1659 MSW(pkt->log.io_param[10]); 1660 tq->prli_payload_length = 0x14; 1661 } 1662 if (mr != NULL) { 1663 LITTLE_ENDIAN_16(&pkt->log.status); 1664 LITTLE_ENDIAN_32(&pkt->log.io_param[0]); 1665 LITTLE_ENDIAN_32(&pkt->log.io_param[1]); 1666 1667 if (pkt->log.status != CS_COMPLETE) { 1668 EL(ha, "failed, status=%xh, iop0=%xh, iop1=" 1669 "%xh\n", pkt->log.status, 1670 pkt->log.io_param[0], 1671 pkt->log.io_param[1]); 1672 1673 switch (pkt->log.io_param[0]) { 1674 case CS0_NO_LINK: 1675 case CS0_FIRMWARE_NOT_READY: 1676 mr->mb[0] = MBS_COMMAND_ERROR; 1677 mr->mb[1] = 1; 1678 break; 1679 case CS0_NO_IOCB: 1680 case CS0_NO_PCB_ALLOCATED: 1681 mr->mb[0] = MBS_COMMAND_ERROR; 1682 mr->mb[1] = 2; 1683 break; 1684 case CS0_NO_EXCH_CTRL_BLK: 1685 mr->mb[0] = MBS_COMMAND_ERROR; 1686 mr->mb[1] = 3; 1687 break; 1688 case CS0_COMMAND_FAILED: 1689 mr->mb[0] = MBS_COMMAND_ERROR; 1690 mr->mb[1] = 4; 1691 switch (LSB(pkt->log.io_param[1])) { 1692 case CS1_PLOGI_RESPONSE_FAILED: 1693 mr->mb[2] = 3; 1694 break; 1695 case CS1_PRLI_FAILED: 1696 mr->mb[2] = 4; 1697 break; 1698 case CS1_PRLI_RESPONSE_FAILED: 1699 mr->mb[2] = 5; 1700 break; 1701 case CS1_COMMAND_LOGGED_OUT: 1702 mr->mb[2] = 7; 1703 break; 1704 case CS1_PLOGI_FAILED: 1705 default: 1706 EL(ha, "log iop1 = %xh\n", 1707 LSB(pkt->log.io_param[1])) 1708 mr->mb[2] = 2; 1709 break; 1710 } 1711 break; 1712 case CS0_PORT_NOT_LOGGED_IN: 1713 mr->mb[0] = MBS_COMMAND_ERROR; 1714 mr->mb[1] = 4; 1715 mr->mb[2] = 7; 1716 break; 1717 case CS0_NO_FLOGI_ACC: 1718 case CS0_NO_FABRIC_PRESENT: 1719 mr->mb[0] = MBS_COMMAND_ERROR; 1720 mr->mb[1] = 5; 1721 break; 1722 case CS0_ELS_REJECT_RECEIVED: 1723 mr->mb[0] = MBS_COMMAND_ERROR; 1724 mr->mb[1] = 0xd; 1725 break; 1726 case CS0_PORT_ID_USED: 1727 mr->mb[0] = MBS_PORT_ID_USED; 1728 mr->mb[1] = LSW(pkt->log.io_param[1]); 1729 break; 1730 case CS0_N_PORT_HANDLE_USED: 1731 mr->mb[0] = MBS_LOOP_ID_USED; 1732 mr->mb[1] = MSW(pkt->log.io_param[1]); 1733 mr->mb[2] = LSW(pkt->log.io_param[1]); 1734 break; 1735 case CS0_NO_N_PORT_HANDLE_AVAILABLE: 1736 mr->mb[0] = MBS_ALL_IDS_IN_USE; 1737 break; 1738 case CS0_CMD_PARAMETER_ERROR: 1739 default: 1740 EL(ha, "pkt->log iop[0]=%xh\n", 1741 pkt->log.io_param[0]); 1742 mr->mb[0] = 1743 MBS_COMMAND_PARAMETER_ERROR; 1744 break; 1745 } 1746 } else { 1747 QL_PRINT_3(CE_CONT, "(%d): status=%xh\n", 1748 ha->instance, pkt->log.status); 1749 1750 mr->mb[0] = MBS_COMMAND_COMPLETE; 1751 mr->mb[1] = (uint16_t) 1752 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0); 1753 if (pkt->log.io_param[0] & BIT_8) { 1754 mr->mb[1] = (uint16_t) 1755 (mr->mb[1] | BIT_1); 1756 } 1757 } 1758 rval = mr->mb[0]; 1759 } 1760 1761 } 1762 1763 kmem_free(pkt, pkt_size); 1764 1765 if (rval != QL_SUCCESS) { 1766 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1767 } else { 1768 /*EMPTY*/ 1769 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1770 } 1771 1772 return (rval); 1773 } 1774 1775 /* 1776 * ql_get_port_database 1777 * Issue get port database mailbox command 1778 * and copy context to device queue. 1779 * 1780 * Input: 1781 * ha: adapter state pointer. 1782 * tq: target queue pointer. 1783 * opt: options. 1784 * PDF_NONE, PDF_PLOGI, PDF_ADISC 1785 * Returns: 1786 * ql local function return status code. 1787 * 1788 * Context: 1789 * Kernel context. 1790 */ 1791 int 1792 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt) 1793 { 1794 int rval; 1795 dma_mem_t mem_desc; 1796 mbx_cmd_t mc = {0}; 1797 mbx_cmd_t *mcp = &mc; 1798 port_database_23_t *pd23; 1799 1800 ASSERT(!MUTEX_HELD(&ha->mutex)); 1801 1802 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1803 1804 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP); 1805 if (pd23 == NULL) { 1806 rval = QL_MEMORY_ALLOC_FAILED; 1807 EL(ha, "failed, rval = %xh\n", rval); 1808 return (rval); 1809 } 1810 1811 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1812 PORT_DATABASE_SIZE)) != QL_SUCCESS) { 1813 return (QL_MEMORY_ALLOC_FAILED); 1814 } 1815 1816 if (CFG_IST(ha, CFG_CTRL_242581)) { 1817 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1818 mcp->mb[1] = tq->loop_id; 1819 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area); 1820 mcp->mb[5] = (uint16_t)tq->d_id.b.domain; 1821 mcp->mb[9] = ha->vp_index; 1822 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC); 1823 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3| 1824 MBX_2|MBX_1|MBX_0; 1825 } else { 1826 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ? 1827 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE); 1828 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1829 mcp->mb[1] = tq->loop_id; 1830 mcp->mb[10] = opt; 1831 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3| 1832 MBX_2|MBX_1|MBX_0; 1833 } else { 1834 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt); 1835 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1836 } 1837 } 1838 1839 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1840 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1841 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1842 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1843 mcp->in_mb = MBX_0; 1844 mcp->timeout = MAILBOX_TOV; 1845 rval = ql_mailbox_command(ha, mcp); 1846 1847 if (rval == QL_SUCCESS) { 1848 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23); 1849 } 1850 1851 ql_free_dma_resource(ha, &mem_desc); 1852 1853 if (rval == QL_SUCCESS) { 1854 if (CFG_IST(ha, CFG_CTRL_242581)) { 1855 port_database_24_t *pd24 = (port_database_24_t *)pd23; 1856 1857 tq->master_state = pd24->current_login_state; 1858 tq->slave_state = pd24->last_stable_login_state; 1859 if (PD_PORT_LOGIN(tq)) { 1860 /* Names are big endian. */ 1861 bcopy((void *)&pd24->port_name[0], 1862 (void *)&tq->port_name[0], 8); 1863 bcopy((void *)&pd24->node_name[0], 1864 (void *)&tq->node_name[0], 8); 1865 tq->hard_addr.b.al_pa = pd24->hard_address[2]; 1866 tq->hard_addr.b.area = pd24->hard_address[1]; 1867 tq->hard_addr.b.domain = pd24->hard_address[0]; 1868 tq->class3_rcv_data_size = 1869 pd24->receive_data_size; 1870 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1871 tq->prli_svc_param_word_0 = 1872 pd24->PRLI_service_parameter_word_0; 1873 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1874 tq->prli_svc_param_word_3 = 1875 pd24->PRLI_service_parameter_word_3; 1876 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1877 } 1878 } else { 1879 tq->master_state = pd23->master_state; 1880 tq->slave_state = pd23->slave_state; 1881 if (PD_PORT_LOGIN(tq)) { 1882 /* Names are big endian. */ 1883 bcopy((void *)&pd23->port_name[0], 1884 (void *)&tq->port_name[0], 8); 1885 bcopy((void *)&pd23->node_name[0], 1886 (void *)&tq->node_name[0], 8); 1887 tq->hard_addr.b.al_pa = pd23->hard_address[2]; 1888 tq->hard_addr.b.area = pd23->hard_address[1]; 1889 tq->hard_addr.b.domain = pd23->hard_address[0]; 1890 tq->cmn_features = pd23->common_features; 1891 LITTLE_ENDIAN_16(&tq->cmn_features); 1892 tq->conc_sequences = 1893 pd23->total_concurrent_sequences; 1894 LITTLE_ENDIAN_16(&tq->conc_sequences); 1895 tq->relative_offset = 1896 pd23->RO_by_information_category; 1897 LITTLE_ENDIAN_16(&tq->relative_offset); 1898 tq->class3_recipient_ctl = pd23->recipient; 1899 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl); 1900 tq->class3_rcv_data_size = 1901 pd23->receive_data_size; 1902 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1903 tq->class3_conc_sequences = 1904 pd23->concurrent_sequences; 1905 LITTLE_ENDIAN_16(&tq->class3_conc_sequences); 1906 tq->class3_open_sequences_per_exch = 1907 pd23->open_sequences_per_exchange; 1908 LITTLE_ENDIAN_16( 1909 &tq->class3_open_sequences_per_exch); 1910 tq->prli_payload_length = 1911 pd23->PRLI_payload_length; 1912 LITTLE_ENDIAN_16(&tq->prli_payload_length); 1913 tq->prli_svc_param_word_0 = 1914 pd23->PRLI_service_parameter_word_0; 1915 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1916 tq->prli_svc_param_word_3 = 1917 pd23->PRLI_service_parameter_word_3; 1918 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1919 } 1920 } 1921 1922 if (!PD_PORT_LOGIN(tq)) { 1923 EL(ha, "d_id=%xh, loop_id=%xh, not logged in " 1924 "master=%xh, slave=%xh\n", tq->d_id.b24, 1925 tq->loop_id, tq->master_state, tq->slave_state); 1926 rval = QL_NOT_LOGGED_IN; 1927 } else { 1928 tq->flags = tq->prli_svc_param_word_3 & 1929 PRLI_W3_TARGET_FUNCTION ? 1930 tq->flags & ~TQF_INITIATOR_DEVICE : 1931 tq->flags | TQF_INITIATOR_DEVICE; 1932 1933 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) { 1934 tq->flags = tq->prli_svc_param_word_3 & 1935 PRLI_W3_RETRY ? 1936 tq->flags | TQF_TAPE_DEVICE : 1937 tq->flags & ~TQF_TAPE_DEVICE; 1938 } else { 1939 tq->flags &= ~TQF_TAPE_DEVICE; 1940 } 1941 } 1942 } 1943 1944 kmem_free(pd23, PORT_DATABASE_SIZE); 1945 1946 if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) { 1947 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1948 tq->loop_id, rval); 1949 } else { 1950 /*EMPTY*/ 1951 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1952 } 1953 1954 return (rval); 1955 } 1956 1957 /* 1958 * ql_get_loop_position_map 1959 * Issue get loop position map mailbox command. 1960 * 1961 * Input: 1962 * ha: adapter state pointer. 1963 * size: size of data buffer. 1964 * bufp: data pointer for DMA data. 1965 * 1966 * Returns: 1967 * ql local function return status code. 1968 * 1969 * Context: 1970 * Kernel context. 1971 */ 1972 int 1973 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 1974 { 1975 int rval; 1976 dma_mem_t mem_desc; 1977 mbx_cmd_t mc = {0}; 1978 mbx_cmd_t *mcp = &mc; 1979 1980 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1981 1982 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1983 (uint32_t)size)) != QL_SUCCESS) { 1984 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 1985 return (QL_MEMORY_ALLOC_FAILED); 1986 } 1987 1988 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 1989 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1990 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1991 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1992 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1993 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1994 mcp->in_mb = MBX_1|MBX_0; 1995 mcp->timeout = MAILBOX_TOV; 1996 rval = ql_mailbox_command(ha, mcp); 1997 1998 if (rval == QL_SUCCESS) { 1999 ql_get_mbox_dma_data(&mem_desc, bufp); 2000 } 2001 2002 ql_free_dma_resource(ha, &mem_desc); 2003 2004 if (rval != QL_SUCCESS) { 2005 EL(ha, "failed=%xh\n", rval); 2006 } else { 2007 /*EMPTY*/ 2008 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2009 } 2010 2011 return (rval); 2012 } 2013 2014 /* 2015 * ql_set_rnid_params 2016 * Issue set RNID parameters mailbox command. 2017 * 2018 * Input: 2019 * ha: adapter state pointer. 2020 * size: size of data buffer. 2021 * bufp: data pointer for DMA data. 2022 * 2023 * Returns: 2024 * ql local function return status code. 2025 * 2026 * Context: 2027 * Kernel context. 2028 */ 2029 int 2030 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2031 { 2032 int rval; 2033 dma_mem_t mem_desc; 2034 mbx_cmd_t mc = {0}; 2035 mbx_cmd_t *mcp = &mc; 2036 2037 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2038 2039 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp, 2040 (uint32_t)size)) != QL_SUCCESS) { 2041 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval); 2042 return (rval); 2043 } 2044 2045 mcp->mb[0] = MBC_SET_PARAMETERS; 2046 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2047 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2048 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2049 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2050 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2051 mcp->in_mb = MBX_0; 2052 mcp->timeout = MAILBOX_TOV; 2053 rval = ql_mailbox_command(ha, mcp); 2054 2055 ql_free_dma_resource(ha, &mem_desc); 2056 2057 if (rval != QL_SUCCESS) { 2058 EL(ha, "failed, rval = %xh\n", rval); 2059 } else { 2060 /*EMPTY*/ 2061 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2062 } 2063 2064 return (rval); 2065 } 2066 2067 /* 2068 * ql_send_rnid_els 2069 * Issue a send node identfication data mailbox command. 2070 * 2071 * Input: 2072 * ha: adapter state pointer. 2073 * loop_id: FC loop id. 2074 * opt: options. 2075 * size: size of data buffer. 2076 * bufp: data pointer for DMA data. 2077 * 2078 * Returns: 2079 * ql local function return status code. 2080 * 2081 * Context: 2082 * Kernel context. 2083 */ 2084 int 2085 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt, 2086 size_t size, caddr_t bufp) 2087 { 2088 int rval; 2089 dma_mem_t mem_desc; 2090 mbx_cmd_t mc = {0}; 2091 mbx_cmd_t *mcp = &mc; 2092 2093 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2094 2095 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2096 (uint32_t)size)) != QL_SUCCESS) { 2097 return (QL_MEMORY_ALLOC_FAILED); 2098 } 2099 2100 mcp->mb[0] = MBC_SEND_RNID_ELS; 2101 if (CFG_IST(ha, CFG_CTRL_242581)) { 2102 mcp->mb[1] = loop_id; 2103 mcp->mb[9] = ha->vp_index; 2104 mcp->mb[10] = opt; 2105 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2106 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2107 mcp->mb[1] = loop_id; 2108 mcp->mb[10] = opt; 2109 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2110 } else { 2111 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 2112 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2113 } 2114 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2115 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2116 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2117 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2118 mcp->in_mb = MBX_0; 2119 mcp->timeout = MAILBOX_TOV; 2120 rval = ql_mailbox_command(ha, mcp); 2121 2122 if (rval == QL_SUCCESS) { 2123 ql_get_mbox_dma_data(&mem_desc, bufp); 2124 } 2125 2126 ql_free_dma_resource(ha, &mem_desc); 2127 2128 if (rval != QL_SUCCESS) { 2129 EL(ha, "failed, rval = %xh\n", rval); 2130 } else { 2131 /*EMPTY*/ 2132 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2133 } 2134 2135 return (rval); 2136 } 2137 2138 /* 2139 * ql_get_rnid_params 2140 * Issue get RNID parameters mailbox command. 2141 * 2142 * Input: 2143 * ha: adapter state pointer. 2144 * size: size of data buffer. 2145 * bufp: data pointer for DMA data. 2146 * 2147 * Returns: 2148 * ql local function return status code. 2149 * 2150 * Context: 2151 * Kernel context. 2152 */ 2153 int 2154 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2155 { 2156 int rval; 2157 dma_mem_t mem_desc; 2158 mbx_cmd_t mc = {0}; 2159 mbx_cmd_t *mcp = &mc; 2160 2161 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2162 2163 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2164 (uint32_t)size)) != QL_SUCCESS) { 2165 return (QL_MEMORY_ALLOC_FAILED); 2166 } 2167 2168 mcp->mb[0] = MBC_GET_PARAMETERS; 2169 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2170 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2171 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2172 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2173 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2174 mcp->in_mb = MBX_0; 2175 mcp->timeout = MAILBOX_TOV; 2176 rval = ql_mailbox_command(ha, mcp); 2177 2178 if (rval == QL_SUCCESS) { 2179 ql_get_mbox_dma_data(&mem_desc, bufp); 2180 } 2181 2182 ql_free_dma_resource(ha, &mem_desc); 2183 2184 if (rval != QL_SUCCESS) { 2185 EL(ha, "failed=%xh\n", rval); 2186 } else { 2187 /*EMPTY*/ 2188 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2189 } 2190 2191 return (rval); 2192 } 2193 2194 /* 2195 * ql_get_link_status 2196 * Issue get link status mailbox command. 2197 * 2198 * Input: 2199 * ha: adapter state pointer. 2200 * loop_id: FC loop id or n_port_hdl. 2201 * size: size of data buffer. 2202 * bufp: data pointer for DMA data. 2203 * port_no: port number to query. 2204 * 2205 * Returns: 2206 * ql local function return status code. 2207 * 2208 * Context: 2209 * Kernel context. 2210 */ 2211 int 2212 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2213 caddr_t bufp, uint8_t port_no) 2214 { 2215 dma_mem_t mem_desc; 2216 mbx_cmd_t mc = {0}; 2217 mbx_cmd_t *mcp = &mc; 2218 int rval = QL_SUCCESS; 2219 int retry = 0; 2220 2221 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2222 2223 do { 2224 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2225 (uint32_t)size)) != QL_SUCCESS) { 2226 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2227 return (QL_MEMORY_ALLOC_FAILED); 2228 } 2229 2230 mcp->mb[0] = MBC_GET_LINK_STATUS; 2231 if (CFG_IST(ha, CFG_CTRL_242581)) { 2232 if (loop_id == ha->loop_id) { 2233 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2234 mcp->mb[8] = (uint16_t)(size >> 2); 2235 mcp->out_mb = MBX_10|MBX_8; 2236 } else { 2237 mcp->mb[1] = loop_id; 2238 mcp->mb[4] = port_no; 2239 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0); 2240 mcp->out_mb = MBX_10|MBX_4; 2241 } 2242 } else { 2243 if (retry) { 2244 port_no = (uint8_t)(port_no | BIT_3); 2245 } 2246 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2247 mcp->mb[1] = loop_id; 2248 mcp->mb[10] = port_no; 2249 mcp->out_mb = MBX_10; 2250 } else { 2251 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2252 port_no); 2253 mcp->out_mb = 0; 2254 } 2255 } 2256 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2257 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2258 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2259 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2260 mcp->in_mb = MBX_1|MBX_0; 2261 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2262 mcp->timeout = MAILBOX_TOV; 2263 2264 rval = ql_mailbox_command(ha, mcp); 2265 2266 if (rval == QL_SUCCESS) { 2267 ql_get_mbox_dma_data(&mem_desc, bufp); 2268 } 2269 2270 ql_free_dma_resource(ha, &mem_desc); 2271 2272 if (rval != QL_SUCCESS) { 2273 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2274 } 2275 2276 /* 2277 * Some of the devices want d_id in the payload, 2278 * strictly as per standard. Let's retry. 2279 */ 2280 2281 } while (rval == QL_COMMAND_ERROR && !retry++); 2282 2283 if (rval != QL_SUCCESS) { 2284 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2285 } else { 2286 /*EMPTY*/ 2287 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2288 } 2289 2290 return (rval); 2291 } 2292 2293 /* 2294 * ql_get_status_counts 2295 * Issue get adapter link status counts mailbox command. 2296 * 2297 * Input: 2298 * ha: adapter state pointer. 2299 * loop_id: FC loop id or n_port_hdl. 2300 * size: size of data buffer. 2301 * bufp: data pointer for DMA data. 2302 * port_no: port number to query. 2303 * 2304 * Returns: 2305 * ql local function return status code. 2306 * 2307 * Context: 2308 * Kernel context. 2309 */ 2310 int 2311 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2312 caddr_t bufp, uint8_t port_no) 2313 { 2314 dma_mem_t mem_desc; 2315 mbx_cmd_t mc = {0}; 2316 mbx_cmd_t *mcp = &mc; 2317 int rval = QL_SUCCESS; 2318 2319 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2320 2321 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2322 (uint32_t)size)) != QL_SUCCESS) { 2323 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval); 2324 return (QL_MEMORY_ALLOC_FAILED); 2325 } 2326 2327 if (CFG_IST(ha, CFG_CTRL_242581)) { 2328 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2329 mcp->mb[8] = (uint16_t)(size / 4); 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): started\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_242581)) { 2476 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2477 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_81XX) ? 2478 BIT_1 : BIT_4); 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 if (CFG_IST(ha, CFG_CTRL_2425)) { 2523 mcp->mb[1] = BIT_3; 2524 } else if (CFG_IST(ha, CFG_CTRL_81XX)) { 2525 mcp->mb[1] = BIT_1; 2526 } 2527 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2528 mcp->in_mb = MBX_0; 2529 mcp->timeout = MAILBOX_TOV; 2530 rval = ql_mailbox_command(ha, mcp); 2531 2532 if (rval != QL_SUCCESS) { 2533 EL(ha, "failed, rval = %xh\n", rval); 2534 } else { 2535 /*EMPTY*/ 2536 QL_PRINT_3(CE_CONT, "(%d): done", ha->instance); 2537 } 2538 2539 return (rval); 2540 } 2541 2542 /* 2543 * ql_lip_reset 2544 * Issue lip reset to a port. 2545 * 2546 * Input: 2547 * ha: adapter state pointer. 2548 * loop_id: FC loop id. 2549 * 2550 * Returns: 2551 * ql local function return status code. 2552 * 2553 * Context: 2554 * Kernel context. 2555 */ 2556 int 2557 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id) 2558 { 2559 int rval; 2560 mbx_cmd_t mc = {0}; 2561 mbx_cmd_t *mcp = &mc; 2562 2563 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2564 2565 if (CFG_IST(ha, CFG_CTRL_242581)) { 2566 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2567 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_81XX) ? 2568 BIT_1 : BIT_6); 2569 mcp->mb[3] = ha->loop_reset_delay; 2570 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2571 } else { 2572 mcp->mb[0] = MBC_LIP_RESET; 2573 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2574 mcp->mb[1] = loop_id; 2575 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 2576 } else { 2577 mcp->mb[1] = (uint16_t)(loop_id << 8); 2578 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2579 } 2580 mcp->mb[2] = ha->loop_reset_delay; 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_242581)) { 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_242581)) { 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_242581)) { 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_242581)) { 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_242581)) { 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 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 2981 QL_SUCCESS) { 2982 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 2983 return (rval); 2984 } 2985 2986 mcp->mb[0] = MBC_EXECUTE_IOCB; 2987 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2988 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2989 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2990 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2991 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2992 mcp->in_mb = MBX_1|MBX_0; 2993 mcp->timeout = MAILBOX_TOV + 5; 2994 rval = ql_mailbox_command(ha, mcp); 2995 2996 if (rval == QL_SUCCESS) { 2997 ql_get_mbox_dma_data(&mem_desc, bp); 2998 } 2999 3000 ql_free_dma_resource(ha, &mem_desc); 3001 3002 if (rval != QL_SUCCESS) { 3003 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 3004 } else { 3005 /*EMPTY*/ 3006 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3007 } 3008 3009 return (rval); 3010 } 3011 3012 /* 3013 * ql_mbx_wrap_test 3014 * Mailbox register wrap test. 3015 * 3016 * Input: 3017 * ha: adapter state pointer. 3018 * mr: pointer for in/out mailbox data. 3019 * 3020 * Returns: 3021 * ql local function return status code. 3022 * 3023 * Context: 3024 * Kernel context. 3025 */ 3026 int 3027 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3028 { 3029 int rval; 3030 mbx_cmd_t mc = {0}; 3031 mbx_cmd_t *mcp = &mc; 3032 3033 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3034 3035 if (mr != NULL) { 3036 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 3037 mcp->mb[1] = mr->mb[1]; 3038 mcp->mb[2] = mr->mb[2]; 3039 mcp->mb[3] = mr->mb[3]; 3040 mcp->mb[4] = mr->mb[4]; 3041 mcp->mb[5] = mr->mb[5]; 3042 mcp->mb[6] = mr->mb[6]; 3043 mcp->mb[7] = mr->mb[7]; 3044 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3045 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3046 mcp->timeout = MAILBOX_TOV; 3047 rval = ql_mailbox_command(ha, mcp); 3048 if (rval == QL_SUCCESS) { 3049 mr->mb[1] = mcp->mb[1]; 3050 mr->mb[2] = mcp->mb[2]; 3051 mr->mb[3] = mcp->mb[3]; 3052 mr->mb[4] = mcp->mb[4]; 3053 mr->mb[5] = mcp->mb[5]; 3054 mr->mb[6] = mcp->mb[6]; 3055 mr->mb[7] = mcp->mb[7]; 3056 } 3057 } else { 3058 rval = QL_FUNCTION_PARAMETER_ERROR; 3059 } 3060 3061 if (rval != QL_SUCCESS) { 3062 EL(ha, "failed=%xh\n", rval); 3063 } else { 3064 /*EMPTY*/ 3065 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3066 } 3067 3068 return (rval); 3069 } 3070 3071 /* 3072 * ql_execute_fw 3073 * Start adapter firmware. 3074 * 3075 * Input: 3076 * ha: adapter state pointer. 3077 * 3078 * Returns: 3079 * ql local function return status code. 3080 * 3081 * Context: 3082 * Kernel context. 3083 */ 3084 int 3085 ql_execute_fw(ql_adapter_state_t *ha) 3086 { 3087 int rval; 3088 mbx_cmd_t mc = {0}; 3089 mbx_cmd_t *mcp = &mc; 3090 3091 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3092 3093 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 3094 if (CFG_IST(ha, CFG_CTRL_242581)) { 3095 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 3096 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 3097 } else { 3098 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 3099 } 3100 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3101 mcp->in_mb = MBX_0; 3102 mcp->timeout = MAILBOX_TOV; 3103 rval = ql_mailbox_command(ha, mcp); 3104 3105 if (CFG_IST(ha, CFG_CTRL_2200)) { 3106 rval = QL_SUCCESS; 3107 } 3108 3109 if (rval != QL_SUCCESS) { 3110 EL(ha, "failed=%xh\n", rval); 3111 } else { 3112 /*EMPTY*/ 3113 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3114 } 3115 3116 return (rval); 3117 } 3118 3119 /* 3120 * ql_get_firmware_option 3121 * Get Firmware Options Mailbox Command. 3122 * 3123 * Input: 3124 * ha: adapter state pointer. 3125 * mr: pointer for mailbox data. 3126 * 3127 * Returns: 3128 * ql local function return status code. 3129 * 3130 * Context: 3131 * Kernel context. 3132 */ 3133 int 3134 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3135 { 3136 int rval; 3137 mbx_cmd_t mc = {0}; 3138 mbx_cmd_t *mcp = &mc; 3139 3140 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3141 3142 mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS; 3143 mcp->out_mb = MBX_0; 3144 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3145 mcp->timeout = MAILBOX_TOV; 3146 rval = ql_mailbox_command(ha, mcp); 3147 3148 /* Return mailbox data. */ 3149 if (mr != NULL) { 3150 mr->mb[0] = mcp->mb[0]; 3151 mr->mb[1] = mcp->mb[1]; 3152 mr->mb[2] = mcp->mb[2]; 3153 mr->mb[3] = mcp->mb[3]; 3154 } 3155 3156 if (rval != QL_SUCCESS) { 3157 EL(ha, "failed=%xh\n", rval); 3158 } else { 3159 /*EMPTY*/ 3160 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 3161 } 3162 3163 return (rval); 3164 } 3165 3166 /* 3167 * ql_set_firmware_option 3168 * Set Firmware Options Mailbox Command. 3169 * 3170 * Input: 3171 * ha: adapter state pointer. 3172 * mr: pointer for mailbox data. 3173 * 3174 * Returns: 3175 * ql local function return status code. 3176 * 3177 * Context: 3178 * Kernel context. 3179 */ 3180 int 3181 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3182 { 3183 int rval; 3184 mbx_cmd_t mc = {0}; 3185 mbx_cmd_t *mcp = &mc; 3186 3187 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3188 3189 if (mr != NULL) { 3190 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS; 3191 mcp->mb[1] = mr->mb[1]; 3192 mcp->mb[2] = mr->mb[2]; 3193 mcp->mb[3] = mr->mb[3]; 3194 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3195 mcp->in_mb = MBX_0; 3196 mcp->timeout = MAILBOX_TOV; 3197 rval = ql_mailbox_command(ha, mcp); 3198 } else { 3199 rval = QL_FUNCTION_PARAMETER_ERROR; 3200 } 3201 3202 if (rval != QL_SUCCESS) { 3203 EL(ha, "failed=%xh\n", rval); 3204 } else { 3205 /*EMPTY*/ 3206 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3207 } 3208 3209 return (rval); 3210 } 3211 3212 /* 3213 * ql_init_firmware 3214 * Initialize firmware mailbox command. 3215 * 3216 * Input: 3217 * ha: adapter state pointer. 3218 * ha->init_ctrl_blk = setup for transmit. 3219 * 3220 * Returns: 3221 * ql local function return status code. 3222 * 3223 * Context: 3224 * Kernel context. 3225 */ 3226 int 3227 ql_init_firmware(ql_adapter_state_t *ha) 3228 { 3229 int rval; 3230 dma_mem_t mem_desc; 3231 mbx_cmd_t mc = {0}; 3232 mbx_cmd_t *mcp = &mc; 3233 3234 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3235 3236 if (CFG_IST(ha, CFG_CTRL_242581)) { 3237 WRT32_IO_REG(ha, req_in, 0); 3238 WRT32_IO_REG(ha, resp_out, 0); 3239 WRT32_IO_REG(ha, pri_req_in, 0); 3240 WRT32_IO_REG(ha, atio_req_out, 0); 3241 } else { 3242 WRT16_IO_REG(ha, req_in, 0); 3243 WRT16_IO_REG(ha, resp_out, 0); 3244 } 3245 3246 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 3247 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) != 3248 QL_SUCCESS) { 3249 EL(ha, "dma setup failed=%xh\n", rval); 3250 return (rval); 3251 } 3252 3253 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ? 3254 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE); 3255 3256 if (CFG_IST(ha, CFG_SBUS_CARD)) { 3257 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2200) ? 3258 0x204c : 0x52); 3259 } 3260 3261 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3262 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3263 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3264 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3265 if (CFG_IST(ha, CFG_CTRL_81XX)) { 3266 uint64_t ofst, addr; 3267 ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *) 3268 &ha->init_ctrl_blk.cb24; 3269 3270 mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW; 3271 if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) { 3272 ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb; 3273 addr = mem_desc.cookie.dmac_laddress + ofst; 3274 mcp->mb[10] = MSW(LSD(addr)); 3275 mcp->mb[11] = LSW(LSD(addr)); 3276 mcp->mb[12] = MSW(MSD(addr)); 3277 mcp->mb[13] = LSW(MSD(addr)); 3278 mcp->mb[14] = sizeof (ql_ext_icb_8100_t); 3279 mcp->mb[1] = BIT_0; 3280 } 3281 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6| 3282 MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3283 } else { 3284 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3285 } 3286 mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0; 3287 mcp->timeout = MAILBOX_TOV; 3288 rval = ql_mailbox_command(ha, mcp); 3289 3290 if (rval == QL_SUCCESS) { 3291 ha->sfp_stat = mcp->mb[2]; 3292 } 3293 ql_free_dma_resource(ha, &mem_desc); 3294 3295 if (rval != QL_SUCCESS) { 3296 EL(ha, "failed=%xh\n", rval); 3297 } else { 3298 /*EMPTY*/ 3299 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3300 } 3301 3302 return (rval); 3303 } 3304 3305 /* 3306 * ql_get_firmware_state 3307 * Get adapter firmware state. 3308 * 3309 * Input: 3310 * ha: adapter state pointer. 3311 * mr: pointer for mailbox data. 3312 * 3313 * Returns: 3314 * ql local function return status code. 3315 * 3316 * Context: 3317 * Kernel context. 3318 */ 3319 int 3320 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3321 { 3322 int rval; 3323 mbx_cmd_t mc = {0}; 3324 mbx_cmd_t *mcp = &mc; 3325 3326 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3327 3328 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 3329 mcp->out_mb = MBX_0; 3330 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3331 mcp->timeout = MAILBOX_TOV; 3332 rval = ql_mailbox_command(ha, mcp); 3333 3334 /* Return mailbox data. */ 3335 if (mr != NULL) { 3336 mr->mb[1] = mcp->mb[1]; 3337 mr->mb[2] = mcp->mb[2]; 3338 mr->mb[3] = mcp->mb[3]; 3339 mr->mb[4] = mcp->mb[4]; 3340 mr->mb[5] = mcp->mb[5]; 3341 } 3342 3343 ha->sfp_stat = mcp->mb[2]; 3344 3345 if (rval != QL_SUCCESS) { 3346 EL(ha, "failed=%xh\n", rval); 3347 } else { 3348 /*EMPTY*/ 3349 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3350 } 3351 3352 return (rval); 3353 } 3354 3355 /* 3356 * ql_get_adapter_id 3357 * Get adapter ID and topology. 3358 * 3359 * Input: 3360 * ha: adapter state pointer. 3361 * mr: pointer for mailbox data. 3362 * 3363 * Returns: 3364 * ql local function return status code. 3365 * 3366 * Context: 3367 * Kernel context. 3368 */ 3369 int 3370 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3371 { 3372 int rval; 3373 mbx_cmd_t mc = {0}; 3374 mbx_cmd_t *mcp = &mc; 3375 3376 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3377 3378 mcp->mb[0] = MBC_GET_ID; 3379 if (ha->flags & VP_ENABLED) { 3380 mcp->mb[9] = ha->vp_index; 3381 } 3382 mcp->out_mb = MBX_9|MBX_0; 3383 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6| 3384 MBX_3|MBX_2|MBX_1|MBX_0; 3385 mcp->timeout = MAILBOX_TOV; 3386 3387 rval = ql_mailbox_command(ha, mcp); 3388 3389 /* Return mailbox data. */ 3390 if (mr != NULL) { 3391 mr->mb[1] = mcp->mb[1]; 3392 mr->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ? 3393 0xffff : mcp->mb[1]); 3394 mr->mb[2] = mcp->mb[2]; 3395 mr->mb[3] = mcp->mb[3]; 3396 mr->mb[6] = mcp->mb[6]; 3397 mr->mb[7] = mcp->mb[7]; 3398 mr->mb[8] = mcp->mb[8]; 3399 mr->mb[9] = mcp->mb[9]; 3400 mr->mb[10] = mcp->mb[10]; 3401 mr->mb[11] = mcp->mb[11]; 3402 mr->mb[12] = mcp->mb[12]; 3403 mr->mb[13] = mcp->mb[13]; 3404 } 3405 3406 if (rval != QL_SUCCESS) { 3407 EL(ha, "failed=%xh\n", rval); 3408 } else { 3409 /*EMPTY*/ 3410 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3411 } 3412 3413 return (rval); 3414 } 3415 3416 /* 3417 * ql_get_fw_version 3418 * Get firmware version. 3419 * 3420 * Input: 3421 * ha: adapter state pointer. 3422 * mr: pointer for mailbox data. 3423 * 3424 * Returns: 3425 * ql local function return status code. 3426 * 3427 * Context: 3428 * Kernel context. 3429 */ 3430 int 3431 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3432 { 3433 int rval; 3434 mbx_cmd_t mc = {0}; 3435 mbx_cmd_t *mcp = &mc; 3436 3437 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3438 3439 mcp->mb[0] = MBC_ABOUT_FIRMWARE; 3440 mcp->out_mb = MBX_0; 3441 mcp->in_mb = MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_6|MBX_5| 3442 MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3443 mcp->timeout = MAILBOX_TOV; 3444 rval = ql_mailbox_command(ha, mcp); 3445 3446 /* Return mailbox data. */ 3447 if (mr != NULL) { 3448 mr->mb[1] = mcp->mb[1]; 3449 mr->mb[2] = mcp->mb[2]; 3450 mr->mb[3] = mcp->mb[3]; 3451 mr->mb[4] = mcp->mb[4]; 3452 mr->mb[5] = mcp->mb[5]; 3453 mr->mb[6] = mcp->mb[6]; 3454 mr->mb[8] = mcp->mb[8]; 3455 mr->mb[9] = mcp->mb[9]; 3456 mr->mb[10] = mcp->mb[10]; 3457 mr->mb[11] = mcp->mb[11]; 3458 mr->mb[12] = mcp->mb[12]; 3459 mr->mb[13] = mcp->mb[13]; 3460 } 3461 3462 if (rval != QL_SUCCESS) { 3463 EL(ha, "failed=%xh\n", rval); 3464 } else { 3465 /*EMPTY*/ 3466 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3467 } 3468 3469 return (rval); 3470 } 3471 3472 /* 3473 * ql_data_rate 3474 * Issue data rate Mailbox Command. 3475 * 3476 * Input: 3477 * ha: adapter state pointer. 3478 * mr: pointer for mailbox data. 3479 * 3480 * Returns: 3481 * ql local function return status code. 3482 * 3483 * Context: 3484 * Kernel context. 3485 */ 3486 int 3487 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3488 { 3489 int rval; 3490 mbx_cmd_t mc = {0}; 3491 mbx_cmd_t *mcp = &mc; 3492 3493 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3494 3495 if (mr != NULL) { 3496 mcp->mb[0] = MBC_DATA_RATE; 3497 mcp->mb[1] = mr->mb[1]; 3498 mcp->mb[2] = mr->mb[2]; 3499 mcp->out_mb = MBX_2|MBX_1|MBX_0; 3500 mcp->in_mb = MBX_2|MBX_1|MBX_0; 3501 mcp->timeout = MAILBOX_TOV; 3502 rval = ql_mailbox_command(ha, mcp); 3503 3504 /* Return mailbox data. */ 3505 mr->mb[1] = mcp->mb[1]; 3506 mr->mb[2] = mcp->mb[2]; 3507 } else { 3508 rval = QL_FUNCTION_PARAMETER_ERROR; 3509 } 3510 3511 ha->sfp_stat = mcp->mb[2]; 3512 3513 if (rval != QL_SUCCESS) { 3514 EL(ha, "failed=%xh\n", rval); 3515 } else { 3516 /*EMPTY*/ 3517 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3518 } 3519 3520 return (rval); 3521 } 3522 3523 /* 3524 * ql_Diag_Loopback 3525 * Issue Reset Link Status mailbox command 3526 * 3527 * Input: 3528 * ha: adapter state pointer. 3529 * findex: FCF index. 3530 * bp: buffer pointer. 3531 * size: buffer size. 3532 * opt: command options. 3533 * it_cnt: iteration count. 3534 * mr: pointer for mailbox data. 3535 * 3536 * Returns: 3537 * ql local function return status code. 3538 * 3539 * Context: 3540 * Kernel context. 3541 */ 3542 int 3543 ql_diag_loopback(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp, 3544 uint32_t size, uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr) 3545 { 3546 int rval; 3547 dma_mem_t mem_desc; 3548 mbx_cmd_t mc = {0}; 3549 mbx_cmd_t *mcp = &mc; 3550 3551 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3552 3553 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3554 QL_SUCCESS) { 3555 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3556 return (rval); 3557 } 3558 3559 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 3560 mcp->mb[1] = opt; 3561 mcp->mb[2] = findex; 3562 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3563 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3564 mcp->mb[10] = LSW(size); 3565 mcp->mb[11] = MSW(size); 3566 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3567 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3568 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3569 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3570 mcp->mb[18] = LSW(it_cnt); 3571 mcp->mb[19] = MSW(it_cnt); 3572 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3573 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3574 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 3575 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 3576 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 3577 mcp->timeout = it_cnt / 300; 3578 if (mcp->timeout < MAILBOX_TOV) { 3579 mcp->timeout = MAILBOX_TOV; 3580 } 3581 rval = ql_mailbox_command(ha, mcp); 3582 3583 if (rval == QL_SUCCESS) { 3584 ql_get_mbox_dma_data(&mem_desc, bp); 3585 } 3586 3587 ql_free_dma_resource(ha, &mem_desc); 3588 3589 /* Return mailbox data. */ 3590 if (mr != NULL) { 3591 mr->mb[0] = mcp->mb[0]; 3592 mr->mb[1] = mcp->mb[1]; 3593 mr->mb[2] = mcp->mb[2]; 3594 mr->mb[3] = mcp->mb[3]; 3595 mr->mb[18] = mcp->mb[18]; 3596 mr->mb[19] = mcp->mb[19]; 3597 } 3598 3599 if (rval != QL_SUCCESS) { 3600 EL(ha, "failed=%xh, mb1=%xh\n", rval, 3601 mcp->mb[1]); 3602 } else { 3603 /*EMPTY*/ 3604 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3605 } 3606 3607 return (rval); 3608 } 3609 3610 /* 3611 * ql_diag_echo 3612 * Issue Diag echo mailbox command. Valid for qla23xx HBA's. 3613 * 3614 * Input: 3615 * ha: adapter state pointer. 3616 * findex: FCF index. 3617 * bp: buffer pointer. 3618 * size: buffer size. 3619 * opt: command options. 3620 * mr: pointer to mailbox status. 3621 * 3622 * Returns: 3623 * ql local function return status code. 3624 * 3625 * Context: 3626 * Kernel context. 3627 */ 3628 int 3629 ql_diag_echo(ql_adapter_state_t *ha, uint16_t findex, caddr_t bp, 3630 uint32_t size, uint16_t opt, ql_mbx_data_t *mr) 3631 { 3632 int rval; 3633 dma_mem_t mem_desc; 3634 mbx_cmd_t mc = {0}; 3635 mbx_cmd_t *mcp = &mc; 3636 3637 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3638 3639 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3640 QL_SUCCESS) { 3641 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3642 return (rval); 3643 } 3644 3645 mcp->mb[0] = MBC_ECHO; 3646 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_81XX) ? opt : 3647 (opt | BIT_6)); 3648 mcp->mb[2] = findex; 3649 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3650 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3651 mcp->mb[10] = LSW(size); 3652 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3653 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3654 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3655 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3656 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3657 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3658 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| 3659 MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 3660 mcp->in_mb = MBX_1|MBX_0; 3661 mcp->timeout = MAILBOX_TOV; 3662 rval = ql_mailbox_command(ha, mcp); 3663 3664 if (rval == QL_SUCCESS) { 3665 ql_get_mbox_dma_data(&mem_desc, bp); 3666 } 3667 3668 ql_free_dma_resource(ha, &mem_desc); 3669 3670 if (mr != NULL) { 3671 mr->mb[0] = mcp->mb[0]; 3672 } 3673 3674 if (rval != QL_SUCCESS) { 3675 EL(ha, "failed=%xh, mb1=%xh\n", rval, 3676 mcp->mb[1]); 3677 } else { 3678 /*EMPTY*/ 3679 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3680 } 3681 3682 return (rval); 3683 } 3684 3685 /* 3686 * ql_serdes_param 3687 * Set/Get serdes transmit parameters mailbox command. 3688 * 3689 * Input: 3690 * ha: adapter state pointer. 3691 * mr: pointer to mailbox in/out parameters. 3692 * 3693 * Returns: 3694 * ql local function return status code. 3695 * 3696 * Context: 3697 * Kernel context. 3698 */ 3699 int 3700 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3701 { 3702 int rval; 3703 mbx_cmd_t mc = {0}; 3704 mbx_cmd_t *mcp = &mc; 3705 3706 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3707 3708 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS; 3709 mcp->mb[1] = mr->mb[1]; 3710 mcp->mb[2] = mr->mb[2]; 3711 mcp->mb[3] = mr->mb[3]; 3712 mcp->mb[4] = mr->mb[4]; 3713 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3714 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0; 3715 mcp->timeout = MAILBOX_TOV; 3716 rval = ql_mailbox_command(ha, mcp); 3717 3718 /* Return mailbox data. */ 3719 if (mr != NULL) { 3720 mr->mb[0] = mcp->mb[0]; 3721 mr->mb[2] = mcp->mb[2]; 3722 mr->mb[3] = mcp->mb[3]; 3723 mr->mb[4] = mcp->mb[4]; 3724 } 3725 3726 if (rval != QL_SUCCESS) { 3727 EL(ha, "failed=%xh\n", rval); 3728 } else { 3729 /*EMPTY*/ 3730 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3731 } 3732 3733 return (rval); 3734 } 3735 3736 /* 3737 * ql_get_timeout_parameters 3738 * Issue get timeout parameters mailbox command. 3739 * 3740 * Input: 3741 * ha: adapter state pointer. 3742 * mr: pointer to mailbox in/out parameters. 3743 * 3744 * Returns: 3745 * ql local function return status code. 3746 * 3747 * Context: 3748 * Kernel context. 3749 */ 3750 int 3751 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov) 3752 { 3753 int rval; 3754 mbx_cmd_t mc = {0}; 3755 mbx_cmd_t *mcp = &mc; 3756 3757 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3758 3759 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS; 3760 mcp->out_mb = MBX_0; 3761 mcp->in_mb = MBX_3|MBX_0; 3762 mcp->timeout = MAILBOX_TOV; 3763 rval = ql_mailbox_command(ha, mcp); 3764 if (rval == QL_SUCCESS) { 3765 /* Get 2 * R_A_TOV in seconds */ 3766 if (CFG_IST(ha, CFG_CTRL_2200) || mcp->mb[3] == 0) { 3767 *tov = R_A_TOV_DEFAULT; 3768 } else { 3769 *tov = (uint16_t)(mcp->mb[3] / 10); 3770 if (mcp->mb[3] % 10 != 0) { 3771 *tov = (uint16_t)(*tov + 1); 3772 } 3773 /* 3774 * Adjust value to prevent driver timeout at the same 3775 * time as device. 3776 */ 3777 *tov = (uint16_t)(*tov + 5); 3778 } 3779 } else { 3780 *tov = R_A_TOV_DEFAULT; 3781 } 3782 3783 if (rval != QL_SUCCESS) { 3784 EL(ha, "failed=%xh\n", rval); 3785 } else { 3786 /*EMPTY*/ 3787 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3788 } 3789 3790 return (rval); 3791 } 3792 3793 /* 3794 * ql_stop_firmware 3795 * Issue stop firmware Mailbox Command. 3796 * 3797 * Input: 3798 * ha: adapter state pointer. 3799 * 3800 * Returns: 3801 * ql local function return status code. 3802 * 3803 * Context: 3804 * Kernel context. 3805 */ 3806 int 3807 ql_stop_firmware(ql_adapter_state_t *ha) 3808 { 3809 int rval; 3810 mbx_cmd_t mc = {0}; 3811 mbx_cmd_t *mcp = &mc; 3812 3813 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3814 3815 mcp->mb[0] = MBC_STOP_FIRMWARE; 3816 mcp->out_mb = MBX_0; 3817 mcp->in_mb = MBX_0; 3818 mcp->timeout = MAILBOX_TOV; 3819 rval = ql_mailbox_command(ha, mcp); 3820 3821 if (rval != QL_SUCCESS) { 3822 EL(ha, "failed=%xh\n", rval); 3823 } else { 3824 /*EMPTY*/ 3825 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3826 } 3827 3828 return (rval); 3829 } 3830 3831 /* 3832 * ql_read_sfp 3833 * Issue Read SFP Mailbox command 3834 * 3835 * Input: 3836 * ha: adapter state pointer. 3837 * mem: pointer to dma memory object for command. 3838 * dev: Device address (A0h or A2h). 3839 * addr: Data address on SFP EEPROM (0�255). 3840 * 3841 * Returns: 3842 * ql local function return status code. 3843 * 3844 * Context: 3845 * Kernel context. 3846 */ 3847 int 3848 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev, 3849 uint16_t addr) 3850 { 3851 int rval; 3852 mbx_cmd_t mc = {0}; 3853 mbx_cmd_t *mcp = &mc; 3854 3855 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3856 3857 mcp->mb[0] = MBC_READ_SFP; 3858 mcp->mb[1] = dev; 3859 mcp->mb[2] = MSW(mem->cookies->dmac_address); 3860 mcp->mb[3] = LSW(mem->cookies->dmac_address); 3861 mcp->mb[6] = MSW(mem->cookies->dmac_notused); 3862 mcp->mb[7] = LSW(mem->cookies->dmac_notused); 3863 mcp->mb[8] = LSW(mem->size); 3864 mcp->mb[9] = addr; 3865 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 3866 mcp->in_mb = MBX_1|MBX_0; 3867 mcp->timeout = MAILBOX_TOV; 3868 rval = ql_mailbox_command(ha, mcp); 3869 3870 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size, 3871 DDI_DMA_SYNC_FORKERNEL); 3872 3873 if (rval != QL_SUCCESS) { 3874 EL(ha, "failed=%xh\n", rval); 3875 } else { 3876 /*EMPTY*/ 3877 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3878 } 3879 3880 return (rval); 3881 } 3882 3883 /* 3884 * ql_iidma_rate 3885 * Issue get/set iidma rate command 3886 * 3887 * Input: 3888 * ha: adapter state pointer. 3889 * loop_id: n-port handle to set/get iidma rate. 3890 * idma_rate: Pointer to iidma rate. 3891 * option: iidma firmware option (set or get data). 3892 * 0 --> Get iidma rate 3893 * 1 --> Set iidma rate 3894 * 3895 * Returns: 3896 * ql local function return status code. 3897 * 3898 * Context: 3899 * Kernel context. 3900 */ 3901 int 3902 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate, 3903 uint32_t option) 3904 { 3905 int rval; 3906 mbx_cmd_t mc = {0}; 3907 mbx_cmd_t *mcp = &mc; 3908 3909 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3910 3911 mcp->mb[0] = MBC_PORT_PARAM; 3912 mcp->mb[1] = loop_id; 3913 mcp->mb[2] = (uint16_t)option; 3914 mcp->out_mb = MBX_0|MBX_1|MBX_2; 3915 mcp->in_mb = MBX_0|MBX_1; 3916 3917 if (option & BIT_0) { 3918 mcp->mb[3] = (uint16_t)*idma_rate; 3919 mcp->out_mb |= MBX_3; 3920 } else { 3921 mcp->in_mb |= MBX_3; 3922 } 3923 3924 mcp->timeout = MAILBOX_TOV; 3925 rval = ql_mailbox_command(ha, mcp); 3926 3927 if (rval != QL_SUCCESS) { 3928 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]); 3929 } else { 3930 if (option == 0) { 3931 *idma_rate = mcp->mb[3]; 3932 } 3933 3934 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3935 } 3936 3937 return (rval); 3938 } 3939 3940 /* 3941 * ql_set_xmit_parms 3942 * Set transmit parameters 3943 * 3944 * Input: 3945 * ha: adapter state pointer. 3946 * 3947 * Returns: 3948 * ql local function return status code. 3949 * 3950 * Context: 3951 * Kernel context. 3952 */ 3953 int 3954 ql_set_xmit_parms(ql_adapter_state_t *ha) 3955 { 3956 int rval; 3957 mbx_cmd_t mc = {0}; 3958 mbx_cmd_t *mcp = &mc; 3959 3960 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3961 3962 mcp->mb[0] = MBC_XMIT_PARM; 3963 mcp->mb[1] = BIT_1; 3964 mcp->out_mb = MBX_1|MBX_0; 3965 mcp->in_mb = MBX_0; 3966 mcp->timeout = MAILBOX_TOV; 3967 rval = ql_mailbox_command(ha, mcp); 3968 3969 if (rval != QL_SUCCESS) { 3970 EL(ha, "failed=%xh\n", rval); 3971 } else { 3972 /*EMPTY*/ 3973 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3974 } 3975 return (rval); 3976 } 3977 3978 /* 3979 * ql_fw_etrace 3980 * Firmware extended tracing. 3981 * 3982 * Input: 3983 * ha: adapter state pointer. 3984 * mem: pointer to dma memory object for command. 3985 * opt: options and opcode. 3986 * 3987 * Returns: 3988 * ql local function return status code. 3989 * 3990 * Context: 3991 * Kernel context. 3992 */ 3993 int 3994 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt) 3995 { 3996 int rval = QL_SUCCESS; 3997 mbx_cmd_t mc = {0}; 3998 mbx_cmd_t *mcp = &mc; 3999 uint16_t op_code; 4000 uint64_t time; 4001 4002 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4003 4004 /* currently no supported options */ 4005 op_code = (uint16_t)(opt & ~0xFF00); 4006 4007 mcp->mb[0] = MBC_TRACE_CONTROL; 4008 mcp->mb[1] = op_code; 4009 mcp->in_mb = MBX_0; 4010 mcp->timeout = MAILBOX_TOV; 4011 4012 switch (op_code) { 4013 case FTO_INSERT_TIME_STAMP: 4014 4015 (void) drv_getparm(TIME, &time); 4016 4017 EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time)); 4018 4019 mcp->mb[2] = LSW(LSD(time)); 4020 mcp->mb[3] = MSW(LSD(time)); 4021 mcp->mb[4] = LSW(MSD(time)); 4022 mcp->mb[5] = MSW(MSD(time)); 4023 mcp->out_mb = MBX_0_THRU_5; 4024 break; 4025 4026 case FTO_FCE_TRACE_ENABLE: 4027 /* Firmware Fibre Channel Event Trace Buffer */ 4028 mcp->mb[2] = LSW(mem->cookies->dmac_address); 4029 mcp->mb[3] = MSW(mem->cookies->dmac_address); 4030 mcp->mb[4] = LSW(mem->cookies->dmac_notused); 4031 mcp->mb[5] = MSW(mem->cookies->dmac_notused); 4032 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */ 4033 mcp->mb[8] = (uint16_t)ha->fwfcetraceopt; 4034 mcp->mb[9] = FTO_FCEMAXTRACEBUF; 4035 mcp->mb[10] = FTO_FCEMAXTRACEBUF; 4036 mcp->out_mb = MBX_0_THRU_10; 4037 break; 4038 4039 case FTO_EXT_TRACE_ENABLE: 4040 /* Firmware Extended Trace Buffer */ 4041 mcp->mb[2] = LSW(mem->cookies->dmac_address); 4042 mcp->mb[3] = MSW(mem->cookies->dmac_address); 4043 mcp->mb[4] = LSW(mem->cookies->dmac_notused); 4044 mcp->mb[5] = MSW(mem->cookies->dmac_notused); 4045 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */ 4046 mcp->out_mb = MBX_0_THRU_7; 4047 break; 4048 4049 case FTO_FCE_TRACE_DISABLE: 4050 /* also causes ISP25xx to flush its internal FCE buffer. */ 4051 mcp->mb[2] = BIT_0; 4052 mcp->out_mb = MBX_0_THRU_2; 4053 break; 4054 4055 case FTO_EXT_TRACE_DISABLE: 4056 /* just sending the opcode disables it */ 4057 break; 4058 4059 default: 4060 EL(ha, "invalid option: %xh\n", opt); 4061 rval = QL_PARAMETER_ERROR; 4062 break; 4063 } 4064 4065 if (rval == QL_SUCCESS) { 4066 rval = ql_mailbox_command(ha, mcp); 4067 } 4068 4069 if (rval != QL_SUCCESS) { 4070 EL(ha, "failed=%xh\n", rval); 4071 } else { 4072 /*EMPTY*/ 4073 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4074 } 4075 4076 return (rval); 4077 } 4078 4079 /* 4080 * ql_reset_menlo 4081 * Reset Menlo Mailbox Command. 4082 * 4083 * Input: 4084 * ha: adapter state pointer. 4085 * mr: pointer to mailbox in/out parameters. 4086 * opt: options. 4087 * 4088 * Returns: 4089 * ql local function return status code. 4090 * 4091 * Context: 4092 * Kernel context. 4093 */ 4094 int 4095 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt) 4096 { 4097 int rval; 4098 mbx_cmd_t mc = {0}; 4099 mbx_cmd_t *mcp = &mc; 4100 4101 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4102 4103 mcp->mb[0] = MBC_RESET_MENLO; 4104 mcp->mb[1] = opt; 4105 mcp->out_mb = MBX_1|MBX_0; 4106 mcp->in_mb = MBX_1|MBX_0; 4107 mcp->timeout = MAILBOX_TOV; 4108 rval = ql_mailbox_command(ha, mcp); 4109 4110 /* Return mailbox data. */ 4111 if (mr != NULL) { 4112 mr->mb[0] = mcp->mb[0]; 4113 mr->mb[1] = mcp->mb[1]; 4114 } 4115 4116 if (rval != QL_SUCCESS) { 4117 EL(ha, "failed=%xh\n", rval); 4118 } else { 4119 /*EMPTY*/ 4120 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4121 } 4122 4123 return (rval); 4124 } 4125 4126 /* 4127 * ql_restart_mpi 4128 * The Restart MPI Firmware Mailbox Command will reset the MPI RISC, 4129 * reload MPI firmware from Flash, and execute the firmware. 4130 * 4131 * Input: 4132 * ha: adapter state pointer. 4133 * 4134 * Returns: 4135 * ql local function return status code. 4136 * 4137 * Context: 4138 * Kernel context. 4139 */ 4140 int 4141 ql_restart_mpi(ql_adapter_state_t *ha) 4142 { 4143 int rval; 4144 mbx_cmd_t mc = {0}; 4145 mbx_cmd_t *mcp = &mc; 4146 4147 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4148 4149 mcp->mb[0] = MBC_RESTART_MPI; 4150 mcp->out_mb = MBX_0; 4151 mcp->in_mb = MBX_1|MBX_0; 4152 mcp->timeout = MAILBOX_TOV; 4153 rval = ql_mailbox_command(ha, mcp); 4154 4155 /* Return mailbox data. */ 4156 if (rval != QL_SUCCESS) { 4157 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 4158 } else { 4159 /*EMPTY*/ 4160 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4161 } 4162 4163 return (rval); 4164 } 4165 4166 /* 4167 * ql_idc_request 4168 * Inter-Driver Communication Request. 4169 * 4170 * Input: 4171 * ha: adapter state pointer. 4172 * mr: pointer for mailbox data. 4173 * 4174 * Returns: 4175 * ql local function return status code. 4176 * 4177 * Context: 4178 * Kernel context. 4179 */ 4180 int 4181 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4182 { 4183 int rval; 4184 mbx_cmd_t mc = {0}; 4185 mbx_cmd_t *mcp = &mc; 4186 4187 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4188 4189 mcp->mb[0] = MBC_IDC_REQUEST; 4190 mcp->mb[1] = mr->mb[1]; 4191 mcp->mb[2] = mr->mb[2]; 4192 mcp->mb[3] = mr->mb[3]; 4193 mcp->mb[4] = mr->mb[4]; 4194 mcp->mb[5] = mr->mb[5]; 4195 mcp->mb[6] = mr->mb[6]; 4196 mcp->mb[7] = mr->mb[7]; 4197 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4198 mcp->in_mb = MBX_2|MBX_0; 4199 mcp->timeout = MAILBOX_TOV; 4200 rval = ql_mailbox_command(ha, mcp); 4201 4202 if (rval == QL_SUCCESS) { 4203 if (mr != NULL) { 4204 mr->mb[2] = mcp->mb[2]; 4205 } 4206 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4207 } else { 4208 EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]); 4209 } 4210 4211 return (rval); 4212 } 4213 4214 /* 4215 * ql_idc_ack 4216 * Inter-Driver Communication Acknowledgement. 4217 * 4218 * Input: 4219 * ha: adapter state pointer. 4220 * 4221 * Returns: 4222 * ql local function return status code. 4223 * 4224 * Context: 4225 * Kernel context. 4226 */ 4227 int 4228 ql_idc_ack(ql_adapter_state_t *ha) 4229 { 4230 int rval; 4231 mbx_cmd_t mc = {0}; 4232 mbx_cmd_t *mcp = &mc; 4233 4234 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4235 4236 mcp->mb[0] = MBC_IDC_ACK; 4237 mcp->mb[1] = ha->idc_mb[1]; 4238 mcp->mb[2] = ha->idc_mb[2]; 4239 mcp->mb[3] = ha->idc_mb[3]; 4240 mcp->mb[4] = ha->idc_mb[4]; 4241 mcp->mb[5] = ha->idc_mb[5]; 4242 mcp->mb[6] = ha->idc_mb[6]; 4243 mcp->mb[7] = ha->idc_mb[7]; 4244 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4245 mcp->in_mb = MBX_0; 4246 mcp->timeout = MAILBOX_TOV; 4247 rval = ql_mailbox_command(ha, mcp); 4248 4249 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4250 4251 return (rval); 4252 } 4253 4254 /* 4255 * ql_idc_time_extend 4256 * Inter-Driver Communication Time Extend 4257 * 4258 * Input: 4259 * ha: adapter state pointer. 4260 * mr: pointer for mailbox data. 4261 * 4262 * Returns: 4263 * ql local function return status code. 4264 * 4265 * Context: 4266 * Kernel context. 4267 */ 4268 int 4269 ql_idc_time_extend(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4270 { 4271 int rval; 4272 mbx_cmd_t mc = {0}; 4273 mbx_cmd_t *mcp = &mc; 4274 4275 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4276 4277 mcp->mb[0] = MBC_IDC_TIME_EXTEND; 4278 mcp->mb[1] = mr->mb[1]; 4279 mcp->mb[2] = mr->mb[2]; 4280 mcp->out_mb = MBX_2|MBX_1|MBX_0; 4281 mcp->in_mb = MBX_0; 4282 mcp->timeout = MAILBOX_TOV; 4283 rval = ql_mailbox_command(ha, mcp); 4284 4285 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4286 4287 return (rval); 4288 } 4289 4290 /* 4291 * ql_port_reset 4292 * The Port Reset for the external 10G port associated with this function 4293 * 4294 * Input: 4295 * ha: adapter state pointer. 4296 * 4297 * Returns: 4298 * ql local function return status code. 4299 * 4300 * Context: 4301 * Kernel context. 4302 */ 4303 int 4304 ql_port_reset(ql_adapter_state_t *ha) 4305 { 4306 int rval; 4307 mbx_cmd_t mc = {0}; 4308 mbx_cmd_t *mcp = &mc; 4309 4310 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4311 4312 mcp->mb[0] = MBC_PORT_RESET; 4313 mcp->out_mb = MBX_0; 4314 mcp->in_mb = MBX_0; 4315 mcp->timeout = MAILBOX_TOV; 4316 rval = ql_mailbox_command(ha, mcp); 4317 4318 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4319 4320 return (rval); 4321 } 4322 4323 /* 4324 * ql_set_port_config 4325 * The Set Port Configuration command sets the configuration for the 4326 * external 10G port associated with this function 4327 * 4328 * Input: 4329 * ha: adapter state pointer. 4330 * mr: pointer for mailbox data. 4331 * 4332 * Returns: 4333 * ql local function return status code. 4334 * 4335 * Context: 4336 * Kernel context. 4337 */ 4338 int 4339 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4340 { 4341 int rval; 4342 mbx_cmd_t mc = {0}; 4343 mbx_cmd_t *mcp = &mc; 4344 4345 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4346 4347 mcp->mb[0] = MBC_SET_PORT_CONFIG; 4348 mcp->mb[1] = mr->mb[1]; 4349 mcp->mb[2] = mr->mb[2]; 4350 mcp->mb[3] = mr->mb[3]; 4351 mcp->mb[4] = mr->mb[4]; 4352 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4353 mcp->in_mb = MBX_0; 4354 mcp->timeout = MAILBOX_TOV; 4355 rval = ql_mailbox_command(ha, mcp); 4356 4357 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4358 4359 return (rval); 4360 } 4361 4362 /* 4363 * ql_get_port_config 4364 * The Get Port Configuration command retrieves the current configuration 4365 * for the external 10G port associated with this function 4366 * 4367 * Input: 4368 * ha: adapter state pointer. 4369 * mr: pointer for mailbox data. 4370 * 4371 * Returns: 4372 * ql local function return status code. 4373 * 4374 * Context: 4375 * Kernel context. 4376 */ 4377 int 4378 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4379 { 4380 int rval; 4381 mbx_cmd_t mc = {0}; 4382 mbx_cmd_t *mcp = &mc; 4383 4384 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4385 4386 mcp->mb[0] = MBC_GET_PORT_CONFIG; 4387 mcp->out_mb = MBX_0; 4388 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4389 mcp->timeout = MAILBOX_TOV; 4390 rval = ql_mailbox_command(ha, mcp); 4391 4392 if (rval == QL_SUCCESS) { 4393 if (mr != NULL) { 4394 mr->mb[1] = mcp->mb[1]; 4395 mr->mb[2] = mcp->mb[2]; 4396 mr->mb[3] = mcp->mb[3]; 4397 mr->mb[4] = mcp->mb[4]; 4398 } 4399 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4400 } else { 4401 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n", 4402 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]); 4403 } 4404 4405 return (rval); 4406 } 4407 4408 /* 4409 * ql_flash_access 4410 * The Get Port Configuration command retrieves the current configuration 4411 * for the external 10G port associated with this function 4412 * 4413 * Input: 4414 * ha: adapter state pointer. 4415 * cmd: command. 4416 * start: 32bit word address. 4417 * end: 32bit word address. 4418 * dp: 32bit word pointer. 4419 * 4420 * Returns: 4421 * ql local function return status code. 4422 * 4423 * Context: 4424 * Kernel context. 4425 */ 4426 int 4427 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start, 4428 uint32_t end, uint32_t *dp) 4429 { 4430 int rval; 4431 mbx_cmd_t mc = {0}; 4432 mbx_cmd_t *mcp = &mc; 4433 4434 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4435 4436 mcp->mb[0] = MBC_FLASH_ACCESS; 4437 if (cmd > 0 && cmd < 4) { 4438 mcp->mb[1] = (uint16_t)(FAC_FORCE_SEMA_LOCK | cmd); 4439 } else { 4440 mcp->mb[1] = cmd; 4441 } 4442 mcp->mb[2] = LSW(start); 4443 mcp->mb[3] = MSW(start); 4444 mcp->mb[4] = LSW(end); 4445 mcp->mb[5] = MSW(end); 4446 4447 EL(ha, "mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh\n", 4448 mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4], mcp->mb[5]); 4449 4450 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4451 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4452 mcp->timeout = MAILBOX_TOV; 4453 rval = ql_mailbox_command(ha, mcp); 4454 4455 if (rval != QL_SUCCESS) { 4456 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1], 4457 mcp->mb[2]); 4458 } else { 4459 if (dp != NULL) { 4460 *dp = (uint32_t)mcp->mb[1]; 4461 } 4462 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4463 } 4464 4465 return (rval); 4466 } 4467 4468 /* 4469 * ql_get_xgmac_stats 4470 * Issue et XGMAC Statistics Mailbox command 4471 * 4472 * Input: 4473 * ha: adapter state pointer. 4474 * size: size of data buffer. 4475 * bufp: data pointer for DMA data. 4476 * 4477 * Returns: 4478 * ql local function return status code. 4479 * 4480 * Context: 4481 * Kernel context. 4482 */ 4483 int 4484 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 4485 { 4486 int rval; 4487 dma_mem_t mem_desc; 4488 mbx_cmd_t mc = {0}; 4489 mbx_cmd_t *mcp = &mc; 4490 4491 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4492 4493 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 4494 (uint32_t)size)) != QL_SUCCESS) { 4495 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 4496 return (QL_MEMORY_ALLOC_FAILED); 4497 } 4498 4499 mcp->mb[0] = MBC_GET_XGMAC_STATS; 4500 mcp->mb[2] = MSW(mem_desc.cookie.dmac_address); 4501 mcp->mb[3] = LSW(mem_desc.cookie.dmac_address); 4502 mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused); 4503 mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused); 4504 mcp->mb[8] = (uint16_t)(size >> 2); 4505 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 4506 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4507 mcp->timeout = MAILBOX_TOV; 4508 rval = ql_mailbox_command(ha, mcp); 4509 4510 if (rval == QL_SUCCESS) { 4511 ql_get_mbox_dma_data(&mem_desc, bufp); 4512 } 4513 ql_free_dma_resource(ha, &mem_desc); 4514 4515 if (rval != QL_SUCCESS) { 4516 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1], 4517 mcp->mb[2]); 4518 } else { 4519 /*EMPTY*/ 4520 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4521 } 4522 4523 return (rval); 4524 } 4525 4526 /* 4527 * ql_get_dcbx_params 4528 * Issue get DCBX parameters mailbox command. 4529 * 4530 * Input: 4531 * ha: adapter state pointer. 4532 * size: size of data buffer. 4533 * bufp: data pointer for DMA data. 4534 * 4535 * Returns: 4536 * ql local function return status code. 4537 * 4538 * Context: 4539 * Kernel context. 4540 */ 4541 int 4542 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp) 4543 { 4544 int rval; 4545 dma_mem_t mem_desc; 4546 mbx_cmd_t mc = {0}; 4547 mbx_cmd_t *mcp = &mc; 4548 4549 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4550 4551 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) != 4552 QL_SUCCESS) { 4553 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED); 4554 return (QL_MEMORY_ALLOC_FAILED); 4555 } 4556 4557 mcp->mb[0] = MBC_GET_DCBX_PARAMS; 4558 mcp->mb[1] = 0; /* Return all DCBX paramters */ 4559 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 4560 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 4561 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 4562 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 4563 mcp->mb[8] = (uint16_t)size; 4564 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 4565 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4566 mcp->timeout = MAILBOX_TOV; 4567 rval = ql_mailbox_command(ha, mcp); 4568 4569 if (rval == QL_SUCCESS) { 4570 ql_get_mbox_dma_data(&mem_desc, bufp); 4571 } 4572 4573 ql_free_dma_resource(ha, &mem_desc); 4574 4575 if (rval != QL_SUCCESS) { 4576 EL(ha, "failed=%xh\n", rval); 4577 } else { 4578 /*EMPTY*/ 4579 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4580 } 4581 4582 return (rval); 4583 } 4584