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