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