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