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 2015 QLogic Corporation */ 23 24 /* 25 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 26 */ 27 28 /* 29 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 30 * 31 * *********************************************************************** 32 * * ** 33 * * NOTICE ** 34 * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION ** 35 * * ALL RIGHTS RESERVED ** 36 * * ** 37 * *********************************************************************** 38 * 39 */ 40 41 #include <ql_apps.h> 42 #include <ql_api.h> 43 #include <ql_debug.h> 44 #include <ql_iocb.h> 45 #include <ql_isr.h> 46 #include <ql_mbx.h> 47 #include <ql_nx.h> 48 #include <ql_xioctl.h> 49 50 /* 51 * Local data 52 */ 53 54 /* 55 * Local prototypes 56 */ 57 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *); 58 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint64_t, 59 uint32_t, uint16_t); 60 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *); 61 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *, 62 caddr_t, uint32_t); 63 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *, 64 uint32_t); 65 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t); 66 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t); 67 static int ql_init_req_q(ql_adapter_state_t *, ql_request_q_t *, uint16_t); 68 static int ql_init_rsp_q(ql_adapter_state_t *, ql_response_q_t *, uint16_t); 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(ha, "started, cmd=%xh\n", 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 if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) { 103 EL(vha, "powerdown availability cmd=%xh\n", mcp->mb[0]); 104 MBX_REGISTER_UNLOCK(ha); 105 return (QL_LOCK_TIMEOUT); 106 } 107 ha->mailbox_flags = (uint8_t) 108 (ha->mailbox_flags | MBX_WANT_FLG); 109 110 /* Set timeout after command that is running. */ 111 timer = ha->mailbox_flags & MBX_BUSY_FLG ? 112 (mcp->timeout + 20) : 2; 113 timer = timer * drv_usectohz(1000000); 114 cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait, 115 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK); 116 if (cv_stat == -1 || cv_stat == 0) { 117 /* 118 * The timeout time 'timer' was 119 * reached without the condition 120 * being signaled. 121 */ 122 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & 123 ~MBX_WANT_FLG); 124 cv_broadcast(&ha->cv_mbx_wait); 125 126 /* Release mailbox register lock. */ 127 MBX_REGISTER_UNLOCK(ha); 128 129 if (cv_stat == 0) { 130 EL(vha, "waiting for availability aborted, " 131 "cmd=%xh\n", mcp->mb[0]); 132 return (QL_ABORTED); 133 } 134 EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]); 135 return (QL_LOCK_TIMEOUT); 136 } 137 } 138 139 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG); 140 141 /* Structure pointer for return mailbox registers. */ 142 ha->mcp = mcp; 143 144 /* Load mailbox registers. */ 145 data = mcp->out_mb; 146 for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) { 147 if (data & MBX_0) { 148 WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]); 149 } 150 data >>= 1; 151 } 152 153 /* Issue set host interrupt command. */ 154 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT); 155 if (CFG_IST(ha, CFG_CTRL_82XX)) { 156 WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD); 157 } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 158 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT); 159 } else { 160 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT); 161 } 162 163 /* Wait for command to complete. */ 164 if (ha->flags & INTERRUPTS_ENABLED && 165 !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) && 166 !ddi_in_panic()) { 167 timer = mcp->timeout * drv_usectohz(1000000); 168 while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) && 169 !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) { 170 171 if (cv_reltimedwait(&ha->cv_mbx_intr, 172 &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) { 173 /* 174 * The timeout time 'timer' was 175 * reached without the condition 176 * being signaled. 177 */ 178 EL(vha, "reltimedwait expired cmd=%xh\n", 179 mcp->mb[0]); 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_82XX)) { 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 (CFG_IST(ha, CFG_CTRL_22XX)) { 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(ha, "done\n"); 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(ha, "started\n"); 431 432 if (!CFG_IST(ha, CFG_FCIP_SUPPORT) || ha->vp_index != 0) { 433 ha->flags &= ~IP_INITIALIZED; 434 EL(ha, "HBA does not support IP\n"); 435 return (QL_FUNCTION_FAILED); 436 } 437 438 ha->rcvbuf_ring_ptr = ha->rcv_ring.bp; 439 ha->rcvbuf_ring_index = 0; 440 441 /* Reset all sequence counts. */ 442 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 443 for (link = ha->dev[index].first; link != NULL; 444 link = link->next) { 445 tq = link->base_address; 446 tq->ub_total_seg_cnt = 0; 447 } 448 } 449 450 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 451 (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t)); 452 if (rval != QL_SUCCESS) { 453 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 454 return (rval); 455 } 456 457 mcp->mb[0] = MBC_INITIALIZE_IP; 458 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 459 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 460 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 461 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 462 mcp->mb[8] = 0; 463 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 464 mcp->in_mb = MBX_8|MBX_0; 465 mcp->timeout = MAILBOX_TOV; 466 rval = ql_mailbox_command(ha, mcp); 467 468 ql_free_dma_resource(ha, &mem_desc); 469 470 if (rval == QL_SUCCESS) { 471 ADAPTER_STATE_LOCK(ha); 472 ha->flags |= IP_INITIALIZED; 473 ADAPTER_STATE_UNLOCK(ha); 474 QL_PRINT_3(ha, "done\n"); 475 } else { 476 ha->flags &= ~IP_INITIALIZED; 477 EL(ha, "failed, rval = %xh\n", rval); 478 } 479 return (rval); 480 } 481 482 /* 483 * ql_shutdown_ip 484 * Disconnects firmware IP from system buffers. 485 * 486 * Input: 487 * ha = adapter state pointer. 488 * 489 * Returns: 490 * ql local function return status code. 491 * 492 * Context: 493 * Kernel context. 494 */ 495 int 496 ql_shutdown_ip(ql_adapter_state_t *ha) 497 { 498 int rval; 499 mbx_cmd_t mc = {0}; 500 mbx_cmd_t *mcp = &mc; 501 fc_unsol_buf_t *ubp; 502 ql_srb_t *sp; 503 uint16_t index; 504 505 QL_PRINT_3(ha, "started\n"); 506 507 mcp->mb[0] = MBC_UNLOAD_IP; 508 mcp->out_mb = MBX_0; 509 mcp->in_mb = MBX_0; 510 mcp->timeout = MAILBOX_TOV; 511 rval = ql_mailbox_command(ha, mcp); 512 513 ADAPTER_STATE_LOCK(ha); 514 QL_UB_LOCK(ha); 515 /* Return all unsolicited buffers that ISP-IP has. */ 516 for (index = 0; index < QL_UB_LIMIT; index++) { 517 ubp = ha->ub_array[index]; 518 if (ubp != NULL) { 519 sp = ubp->ub_fca_private; 520 sp->flags &= ~SRB_UB_IN_ISP; 521 } 522 } 523 524 ha->ub_outcnt = 0; 525 QL_UB_UNLOCK(ha); 526 ha->flags &= ~IP_INITIALIZED; 527 ADAPTER_STATE_UNLOCK(ha); 528 529 if (rval == QL_SUCCESS) { 530 /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */ 531 QL_PRINT_3(ha, "done\n"); 532 } else { 533 EL(ha, "failed, rval = %xh\n", rval); 534 } 535 return (rval); 536 } 537 538 /* 539 * ql_online_selftest 540 * Issue online self test mailbox command. 541 * 542 * Input: 543 * ha = adapter state pointer. 544 * 545 * Returns: 546 * ql local function return status code. 547 * 548 * Context: 549 * Kernel context. 550 */ 551 int 552 ql_online_selftest(ql_adapter_state_t *ha) 553 { 554 int rval; 555 mbx_cmd_t mc = {0}; 556 mbx_cmd_t *mcp = &mc; 557 558 QL_PRINT_3(ha, "started\n"); 559 560 mcp->mb[0] = MBC_ONLINE_SELF_TEST; 561 mcp->out_mb = MBX_0; 562 mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3; 563 mcp->timeout = MAILBOX_TOV; 564 rval = ql_mailbox_command(ha, mcp); 565 566 if (rval != QL_SUCCESS) { 567 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n", 568 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]); 569 } else { 570 /*EMPTY*/ 571 QL_PRINT_3(ha, "done\n"); 572 } 573 return (rval); 574 } 575 576 /* 577 * ql_loop_back 578 * Issue diagnostic loop back frame mailbox command. 579 * 580 * Input: 581 * ha: adapter state pointer. 582 * findex: FCF index. 583 * lb: loop back parameter structure pointer. 584 * 585 * Returns: 586 * ql local function return status code. 587 * 588 * Context: 589 * Kernel context. 590 */ 591 #ifndef apps_64bit 592 int 593 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb, 594 uint32_t h_xmit, uint32_t h_rcv) 595 { 596 int rval; 597 mbx_cmd_t mc = {0}; 598 mbx_cmd_t *mcp = &mc; 599 600 QL_PRINT_3(ha, "started\n"); 601 602 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 603 mcp->mb[1] = lb->options; 604 mcp->mb[2] = findex; 605 mcp->mb[6] = LSW(h_rcv); 606 mcp->mb[7] = MSW(h_rcv); 607 mcp->mb[10] = LSW(lb->transfer_count); 608 mcp->mb[11] = MSW(lb->transfer_count); 609 mcp->mb[12] = lb->transfer_segment_count; 610 mcp->mb[13] = lb->receive_segment_count; 611 mcp->mb[14] = LSW(lb->transfer_data_address); 612 mcp->mb[15] = MSW(lb->transfer_data_address); 613 mcp->mb[16] = LSW(lb->receive_data_address); 614 mcp->mb[17] = MSW(lb->receive_data_address); 615 mcp->mb[18] = LSW(lb->iteration_count); 616 mcp->mb[19] = MSW(lb->iteration_count); 617 mcp->mb[20] = LSW(h_xmit); 618 mcp->mb[21] = MSW(h_xmit); 619 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 620 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 621 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 622 mcp->timeout = lb->iteration_count / 300; 623 624 if (mcp->timeout < MAILBOX_TOV) { 625 mcp->timeout = MAILBOX_TOV; 626 } 627 628 rval = ql_mailbox_command(ha, mcp); 629 630 if (rval != QL_SUCCESS) { 631 EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n", 632 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]); 633 } else { 634 /*EMPTY*/ 635 QL_PRINT_3(ha, "done\n"); 636 } 637 return (rval); 638 } 639 #else 640 int 641 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb) 642 { 643 int rval; 644 mbx_cmd_t mc = {0}; 645 mbx_cmd_t *mcp = &mc; 646 647 QL_PRINT_3(ha, "started\n"); 648 649 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 650 mcp->mb[1] = lb->options; 651 mcp->mb[2] = findex; 652 mcp->mb[6] = LSW(h_rcv); 653 mcp->mb[7] = MSW(h_rcv); 654 mcp->mb[6] = LSW(MSD(lb->receive_data_address)); 655 mcp->mb[7] = MSW(MSD(lb->receive_data_address)); 656 mcp->mb[10] = LSW(lb->transfer_count); 657 mcp->mb[11] = MSW(lb->transfer_count); 658 mcp->mb[12] = lb->transfer_segment_count; 659 mcp->mb[13] = lb->receive_segment_count; 660 mcp->mb[14] = LSW(lb->transfer_data_address); 661 mcp->mb[15] = MSW(lb->transfer_data_address); 662 mcp->mb[14] = LSW(LSD(lb->transfer_data_address)); 663 mcp->mb[15] = MSW(LSD(lb->transfer_data_address)); 664 mcp->mb[16] = LSW(lb->receive_data_address); 665 mcp->mb[17] = MSW(lb->receive_data_address); 666 mcp->mb[16] = LSW(LSD(lb->receive_data_address)); 667 mcp->mb[17] = MSW(LSD(lb->receive_data_address)); 668 mcp->mb[18] = LSW(lb->iteration_count); 669 mcp->mb[19] = MSW(lb->iteration_count); 670 mcp->mb[20] = LSW(h_xmit); 671 mcp->mb[21] = MSW(h_xmit); 672 mcp->mb[20] = LSW(MSD(lb->transfer_data_address)); 673 mcp->mb[21] = MSW(MSD(lb->transfer_data_address)); 674 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 675 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 676 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 677 mcp->timeout = lb->iteration_count / 300; 678 679 if (mcp->timeout < MAILBOX_TOV) { 680 mcp->timeout = MAILBOX_TOV; 681 } 682 683 rval = ql_mailbox_command(ha, mcp); 684 685 if (rval != QL_SUCCESS) { 686 EL(ha, "failed, rval = %xh\n", rval); 687 } else { 688 /*EMPTY*/ 689 QL_PRINT_3(ha, "done\n"); 690 } 691 return (rval); 692 } 693 #endif 694 695 /* 696 * ql_echo 697 * Issue an ELS echo using the user specified data to a user specified 698 * destination 699 * 700 * Input: 701 * ha: adapter state pointer. 702 * findex: FCF index. 703 * echo_pt: echo parameter structure pointer. 704 * 705 * Returns: 706 * ql local function return status code. 707 * 708 * Context: 709 * Kernel context. 710 */ 711 int 712 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt) 713 { 714 int rval; 715 mbx_cmd_t mc = {0}; 716 mbx_cmd_t *mcp = &mc; 717 718 QL_PRINT_3(ha, "started\n"); 719 720 mcp->mb[0] = MBC_ECHO; /* ECHO command */ 721 mcp->mb[1] = echo_pt->options; /* command options; 64 bit */ 722 /* addressing (bit 6) and */ 723 /* real echo (bit 15 */ 724 mcp->mb[2] = findex; 725 726 /* 727 * I know this looks strange, using a field labled "not used" 728 * The way the ddi_dma_cookie_t structure/union is defined 729 * is a union of one 64 bit entity with an array of two 32 730 * bit enititys. Since we have routines to convert 32 bit 731 * entities into 16 bit entities it is easier to use 732 * both 32 bit union members then the one 64 bit union 733 * member 734 */ 735 if (echo_pt->options & BIT_6) { 736 /* 64 bit addressing */ 737 /* Receive data dest add in system memory bits 47-32 */ 738 mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused); 739 740 /* Receive data dest add in system memory bits 63-48 */ 741 mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused); 742 743 /* Transmit data source address in system memory bits 47-32 */ 744 mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused); 745 746 /* Transmit data source address in system memory bits 63-48 */ 747 mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused); 748 } 749 750 /* transfer count bits 15-0 */ 751 mcp->mb[10] = LSW(echo_pt->transfer_count); 752 753 /* Transmit data source address in system memory bits 15-0 */ 754 mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address); 755 756 /* Transmit data source address in system memory bits 31-16 */ 757 mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address); 758 759 /* Receive data destination address in system memory bits 15-0 */ 760 mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address); 761 762 /* Receive data destination address in system memory bits 31-16 */ 763 mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address); 764 765 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10| 766 MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 767 mcp->in_mb = MBX_3|MBX_1|MBX_0; 768 mcp->timeout = MAILBOX_TOV; 769 770 rval = ql_mailbox_command(ha, mcp); 771 772 if (rval != QL_SUCCESS) { 773 EL(ha, "failed, rval = %xh\n", rval); 774 } else { 775 /*EMPTY*/ 776 QL_PRINT_3(ha, "done\n"); 777 } 778 return (rval); 779 } 780 781 /* 782 * ql_send_change_request 783 * Issue send change request mailbox command. 784 * 785 * Input: 786 * ha: adapter state pointer. 787 * fmt: Registration format. 788 * 789 * Returns: 790 * ql local function return status code. 791 * 792 * Context: 793 * Kernel context. 794 */ 795 int 796 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt) 797 { 798 int rval; 799 mbx_cmd_t mc = {0}; 800 mbx_cmd_t *mcp = &mc; 801 802 QL_PRINT_3(ha, "started\n"); 803 804 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 805 mcp->mb[1] = fmt; 806 mcp->out_mb = MBX_1|MBX_0; 807 if (ha->flags & VP_ENABLED) { 808 mcp->mb[9] = ha->vp_index; 809 mcp->out_mb |= MBX_9; 810 } 811 mcp->in_mb = MBX_0; 812 mcp->timeout = MAILBOX_TOV; 813 rval = ql_mailbox_command(ha, mcp); 814 815 if (rval != QL_SUCCESS) { 816 EL(ha, "failed=%xh\n", rval); 817 } else { 818 /*EMPTY*/ 819 QL_PRINT_3(ha, "done\n"); 820 } 821 return (rval); 822 } 823 824 /* 825 * ql_send_lfa 826 * Send a Loop Fabric Address mailbox command. 827 * 828 * Input: 829 * ha: adapter state pointer. 830 * lfa: LFA command structure pointer. 831 * 832 * Returns: 833 * ql local function return status code. 834 * 835 * Context: 836 * Kernel context. 837 */ 838 int 839 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa) 840 { 841 int rval; 842 uint16_t size; 843 dma_mem_t mem_desc; 844 mbx_cmd_t mc = {0}; 845 mbx_cmd_t *mcp = &mc; 846 847 QL_PRINT_3(ha, "started\n"); 848 849 /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */ 850 size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1); 851 852 rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size); 853 if (rval != QL_SUCCESS) { 854 EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval); 855 return (rval); 856 } 857 858 mcp->mb[0] = MBC_SEND_LFA_COMMAND; 859 mcp->mb[1] = (uint16_t)(size >> 1); 860 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 861 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 862 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 863 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 864 mcp->in_mb = MBX_0; 865 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 866 if (ha->flags & VP_ENABLED) { 867 mcp->mb[9] = ha->vp_index; 868 mcp->out_mb |= MBX_9; 869 } 870 mcp->timeout = MAILBOX_TOV; 871 rval = ql_mailbox_command(ha, mcp); 872 873 ql_free_dma_resource(ha, &mem_desc); 874 875 if (rval != QL_SUCCESS) { 876 EL(ha, "failed, rval = %xh\n", rval); 877 } else { 878 /*EMPTY*/ 879 QL_PRINT_3(ha, "done\n"); 880 } 881 882 return (rval); 883 } 884 885 /* 886 * ql_clear_aca 887 * Issue clear ACA mailbox command. 888 * 889 * Input: 890 * ha: adapter state pointer. 891 * tq: target queue pointer. 892 * lq: LUN queue pointer. 893 * 894 * Returns: 895 * ql local function return status code. 896 * 897 * Context: 898 * Kernel context. 899 */ 900 int 901 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq) 902 { 903 int rval; 904 mbx_cmd_t mc = {0}; 905 mbx_cmd_t *mcp = &mc; 906 907 QL_PRINT_3(ha, "started\n"); 908 909 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 910 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr, 911 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] = lq->lun_no; 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, lq, 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(ha, "done\n"); 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 ql_srb_t *sp; 958 uint16_t index; 959 int rval = QL_SUCCESS; 960 mbx_cmd_t mc = {0}; 961 mbx_cmd_t *mcp = &mc; 962 963 QL_PRINT_3(ha, "started\n"); 964 965 ql_requeue_pending_cmds(ha, tq); 966 INTR_LOCK(ha); 967 for (index = 1; index < ha->pha->osc_max_cnt; index++) { 968 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 969 sp->lun_queue != NULL && 970 sp->lun_queue->target_queue == tq) { 971 sp->flags |= SRB_ABORTING; 972 } 973 } 974 INTR_UNLOCK(ha); 975 976 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 977 /* queue = NULL, all targets. */ 978 if (tq == NULL) { 979 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; 980 index++) { 981 for (link = ha->dev[index].first; link != 982 NULL; link = link->next) { 983 tq = link->base_address; 984 if (!VALID_DEVICE_ID(ha, 985 tq->loop_id)) { 986 continue; 987 } 988 989 if (CFG_IST(ha, CFG_FAST_TIMEOUT)) { 990 rval = ql_task_mgmt_iocb(ha, 991 tq, 0, CF_DO_NOT_SEND | 992 CF_TARGET_RESET, delay); 993 } else { 994 rval = ql_task_mgmt_iocb(ha, 995 tq, 0, CF_TARGET_RESET, 996 delay); 997 } 998 999 if (rval != QL_SUCCESS) { 1000 break; 1001 } 1002 } 1003 1004 if (link != NULL) { 1005 break; 1006 } 1007 } 1008 tq = NULL; 1009 } else { 1010 1011 if (CFG_IST(ha, CFG_FAST_TIMEOUT)) { 1012 rval = ql_task_mgmt_iocb(ha, tq, 0, 1013 CF_TARGET_RESET | CF_DO_NOT_SEND, delay); 1014 } else { 1015 rval = ql_task_mgmt_iocb(ha, tq, 0, 1016 CF_TARGET_RESET, delay); 1017 } 1018 } 1019 } else { 1020 /* queue = NULL, all targets. */ 1021 if (tq == NULL) { 1022 mcp->mb[0] = MBC_RESET; 1023 mcp->mb[1] = delay; 1024 mcp->out_mb = MBX_1|MBX_0; 1025 } else { 1026 mcp->mb[0] = MBC_TARGET_RESET; 1027 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1028 mcp->mb[1] = tq->loop_id; 1029 } else { 1030 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1031 } 1032 mcp->mb[2] = delay; 1033 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1034 } 1035 mcp->in_mb = MBX_0; 1036 mcp->timeout = MAILBOX_TOV; 1037 rval = ql_mailbox_command(ha, mcp); 1038 } 1039 1040 tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) : 1041 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 1042 1043 if (rval != QL_SUCCESS) { 1044 EL(ha, "failed, rval = %xh\n", rval); 1045 } else { 1046 /*EMPTY*/ 1047 QL_PRINT_3(ha, "done\n"); 1048 } 1049 1050 return (rval); 1051 } 1052 1053 /* 1054 * ql_abort_target 1055 * Issue abort target mailbox command. 1056 * 1057 * Input: 1058 * ha: adapter state pointer. 1059 * tq: target queue pointer. 1060 * delay: in seconds. 1061 * 1062 * Returns: 1063 * ql local function return status code. 1064 * 1065 * Context: 1066 * Kernel context. 1067 */ 1068 int 1069 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay) 1070 { 1071 ql_srb_t *sp; 1072 uint16_t index; 1073 int rval; 1074 mbx_cmd_t mc = {0}; 1075 mbx_cmd_t *mcp = &mc; 1076 1077 QL_PRINT_3(ha, "started\n"); 1078 1079 ql_requeue_pending_cmds(ha, tq); 1080 INTR_LOCK(ha); 1081 for (index = 1; index < ha->pha->osc_max_cnt; index++) { 1082 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 1083 sp->lun_queue != NULL && 1084 sp->lun_queue->target_queue == tq) { 1085 sp->flags |= SRB_ABORTING; 1086 } 1087 } 1088 INTR_UNLOCK(ha); 1089 1090 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1091 rval = ql_task_mgmt_iocb(ha, tq, 0, 1092 CF_DO_NOT_SEND | CF_TARGET_RESET, delay); 1093 } else { 1094 mcp->mb[0] = MBC_ABORT_TARGET; 1095 /* Don't send Task Mgt */ 1096 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1097 mcp->mb[1] = tq->loop_id; 1098 mcp->mb[10] = BIT_0; 1099 mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0; 1100 } else { 1101 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0); 1102 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1103 } 1104 mcp->mb[2] = delay; 1105 mcp->in_mb = MBX_0; 1106 mcp->timeout = MAILBOX_TOV; 1107 rval = ql_mailbox_command(ha, mcp); 1108 } 1109 1110 (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID); 1111 1112 if (rval != QL_SUCCESS) { 1113 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1114 } else { 1115 /*EMPTY*/ 1116 QL_PRINT_3(ha, "done\n"); 1117 } 1118 return (rval); 1119 } 1120 1121 /* 1122 * ql_lun_reset 1123 * Issue LUN reset task management mailbox command. 1124 * 1125 * Input: 1126 * ha: adapter state pointer. 1127 * tq: target queue pointer. 1128 * lq: LUN queue pointer. 1129 * 1130 * Returns: 1131 * ql local function return status code. 1132 * 1133 * Context: 1134 * Kernel context. 1135 */ 1136 int 1137 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq) 1138 { 1139 ql_srb_t *sp; 1140 uint16_t index; 1141 int rval; 1142 mbx_cmd_t mc = {0}; 1143 mbx_cmd_t *mcp = &mc; 1144 1145 QL_PRINT_3(ha, "started\n"); 1146 1147 ql_requeue_pending_cmds(ha, tq); 1148 INTR_LOCK(ha); 1149 for (index = 1; index < ha->pha->osc_max_cnt; index++) { 1150 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 1151 sp->lun_queue != NULL && 1152 sp->lun_queue->target_queue == tq && 1153 sp->lun_queue == lq) { 1154 sp->flags |= SRB_ABORTING; 1155 } 1156 } 1157 INTR_UNLOCK(ha); 1158 1159 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1160 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr, 1161 CF_LUN_RESET, 0); 1162 } else { 1163 mcp->mb[0] = MBC_LUN_RESET; 1164 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1165 mcp->mb[1] = tq->loop_id; 1166 } else { 1167 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1168 } 1169 mcp->mb[2] = lq->lun_no; 1170 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1171 mcp->in_mb = MBX_0; 1172 mcp->timeout = MAILBOX_TOV; 1173 rval = ql_mailbox_command(ha, mcp); 1174 } 1175 1176 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID); 1177 1178 if (rval != QL_SUCCESS) { 1179 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1180 } else { 1181 /*EMPTY*/ 1182 QL_PRINT_3(ha, "done\n"); 1183 } 1184 return (rval); 1185 } 1186 1187 /* 1188 * ql_clear_task_set 1189 * Issue clear task set mailbox command. 1190 * 1191 * Input: 1192 * ha: adapter state pointer. 1193 * tq: target queue pointer. 1194 * lq: LUN queue pointer. 1195 * 1196 * Returns: 1197 * ql local function return status code. 1198 * 1199 * Context: 1200 * Kernel context. 1201 */ 1202 int 1203 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq) 1204 { 1205 ql_srb_t *sp; 1206 uint16_t index; 1207 int rval; 1208 mbx_cmd_t mc = {0}; 1209 mbx_cmd_t *mcp = &mc; 1210 1211 QL_PRINT_3(ha, "started\n"); 1212 1213 ql_requeue_pending_cmds(ha, tq); 1214 INTR_LOCK(ha); 1215 for (index = 1; index < ha->pha->osc_max_cnt; index++) { 1216 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 1217 sp->lun_queue != NULL && 1218 sp->lun_queue->target_queue == tq && 1219 sp->lun_queue == lq) { 1220 sp->flags |= SRB_ABORTING; 1221 } 1222 } 1223 INTR_UNLOCK(ha); 1224 1225 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1226 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr, 1227 CF_CLEAR_TASK_SET, 0); 1228 } else { 1229 mcp->mb[0] = MBC_CLEAR_TASK_SET; 1230 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1231 mcp->mb[1] = tq->loop_id; 1232 } else { 1233 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1234 } 1235 mcp->mb[2] = lq->lun_no; 1236 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1237 mcp->in_mb = MBX_0; 1238 mcp->timeout = MAILBOX_TOV; 1239 rval = ql_mailbox_command(ha, mcp); 1240 } 1241 1242 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID); 1243 1244 if (rval != QL_SUCCESS) { 1245 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1246 } else { 1247 /*EMPTY*/ 1248 QL_PRINT_3(ha, "done\n"); 1249 } 1250 1251 return (rval); 1252 } 1253 1254 /* 1255 * ql_abort_task_set 1256 * Issue abort task set mailbox command. 1257 * 1258 * Input: 1259 * ha: adapter state pointer. 1260 * tq: target queue pointer. 1261 * lq: LUN queue pointer. 1262 * 1263 * Returns: 1264 * ql local function return status code. 1265 * 1266 * Context: 1267 * Kernel context. 1268 */ 1269 int 1270 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq) 1271 { 1272 ql_srb_t *sp; 1273 uint16_t index; 1274 int rval; 1275 mbx_cmd_t mc = {0}; 1276 mbx_cmd_t *mcp = &mc; 1277 1278 QL_PRINT_3(ha, "started\n"); 1279 1280 ql_requeue_pending_cmds(ha, tq); 1281 INTR_LOCK(ha); 1282 for (index = 1; index < ha->pha->osc_max_cnt; index++) { 1283 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 1284 sp->lun_queue != NULL && 1285 sp->lun_queue->target_queue == tq && 1286 sp->lun_queue == lq) { 1287 sp->flags |= SRB_ABORTING; 1288 } 1289 } 1290 INTR_UNLOCK(ha); 1291 1292 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1293 rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr, 1294 CF_ABORT_TASK_SET, 0); 1295 } else { 1296 mcp->mb[0] = MBC_ABORT_TASK_SET; 1297 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1298 mcp->mb[1] = tq->loop_id; 1299 } else { 1300 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1301 } 1302 mcp->mb[2] = lq->lun_no; 1303 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1304 mcp->in_mb = MBX_0; 1305 mcp->timeout = MAILBOX_TOV; 1306 rval = ql_mailbox_command(ha, mcp); 1307 } 1308 1309 (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID); 1310 1311 if (rval != QL_SUCCESS) { 1312 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1313 } else { 1314 /*EMPTY*/ 1315 QL_PRINT_3(ha, "done\n"); 1316 } 1317 1318 return (rval); 1319 } 1320 1321 /* 1322 * ql_task_mgmt_iocb 1323 * Function issues task management IOCB. 1324 * 1325 * Input: 1326 * ha: adapter state pointer. 1327 * tq: target queue pointer. 1328 * lun_addr: LUN. 1329 * flags: control flags. 1330 * delay: seconds. 1331 * 1332 * Returns: 1333 * ql local function return status code. 1334 * 1335 * Context: 1336 * Kernel context 1337 */ 1338 static int 1339 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint64_t lun_addr, 1340 uint32_t flags, uint16_t delay) 1341 { 1342 ql_mbx_iocb_t *pkt; 1343 int rval; 1344 uint32_t pkt_size; 1345 fcp_ent_addr_t *fcp_ent_addr; 1346 1347 QL_PRINT_3(ha, "started\n"); 1348 1349 pkt_size = sizeof (ql_mbx_iocb_t); 1350 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1351 if (pkt == NULL) { 1352 EL(ha, "failed, kmem_zalloc\n"); 1353 return (QL_MEMORY_ALLOC_FAILED); 1354 } 1355 1356 pkt->mgmt.entry_type = TASK_MGMT_TYPE; 1357 pkt->mgmt.entry_count = 1; 1358 1359 pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 1360 pkt->mgmt.delay = (uint16_t)LE_16(delay); 1361 pkt->mgmt.timeout = LE_16(MAILBOX_TOV); 1362 1363 fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr; 1364 pkt->mgmt.fcp_lun[2] = lobyte(fcp_ent_addr->ent_addr_0); 1365 pkt->mgmt.fcp_lun[3] = hibyte(fcp_ent_addr->ent_addr_0); 1366 pkt->mgmt.fcp_lun[0] = lobyte(fcp_ent_addr->ent_addr_1); 1367 pkt->mgmt.fcp_lun[1] = hibyte(fcp_ent_addr->ent_addr_1); 1368 pkt->mgmt.fcp_lun[6] = lobyte(fcp_ent_addr->ent_addr_2); 1369 pkt->mgmt.fcp_lun[7] = hibyte(fcp_ent_addr->ent_addr_2); 1370 pkt->mgmt.fcp_lun[4] = lobyte(fcp_ent_addr->ent_addr_3); 1371 pkt->mgmt.fcp_lun[5] = hibyte(fcp_ent_addr->ent_addr_3); 1372 1373 pkt->mgmt.control_flags = LE_32(flags); 1374 pkt->mgmt.target_id[0] = tq->d_id.b.al_pa; 1375 pkt->mgmt.target_id[1] = tq->d_id.b.area; 1376 pkt->mgmt.target_id[2] = tq->d_id.b.domain; 1377 pkt->mgmt.vp_index = ha->vp_index; 1378 1379 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1380 if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) { 1381 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1382 pkt->sts24.entry_status, tq->d_id.b24); 1383 rval = QL_FUNCTION_PARAMETER_ERROR; 1384 } 1385 1386 LITTLE_ENDIAN_16(&pkt->sts24.comp_status); 1387 1388 if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) { 1389 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 1390 pkt->sts24.comp_status, tq->d_id.b24); 1391 rval = QL_FUNCTION_FAILED; 1392 } 1393 1394 kmem_free(pkt, pkt_size); 1395 1396 if (rval != QL_SUCCESS) { 1397 EL(ha, "failed, rval = %xh\n", rval); 1398 } else { 1399 /*EMPTY*/ 1400 QL_PRINT_3(ha, "done\n"); 1401 } 1402 1403 return (rval); 1404 } 1405 1406 /* 1407 * ql_loop_port_bypass 1408 * Issue loop port bypass mailbox command. 1409 * 1410 * Input: 1411 * ha: adapter state pointer. 1412 * tq: target queue pointer. 1413 * 1414 * Returns: 1415 * ql local function return status code. 1416 * 1417 * Context: 1418 * Kernel context. 1419 */ 1420 int 1421 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq) 1422 { 1423 int rval; 1424 mbx_cmd_t mc = {0}; 1425 mbx_cmd_t *mcp = &mc; 1426 1427 QL_PRINT_3(ha, "started\n"); 1428 1429 mcp->mb[0] = MBC_LOOP_PORT_BYPASS; 1430 1431 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1432 mcp->mb[1] = tq->d_id.b.al_pa; 1433 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1434 mcp->mb[1] = tq->loop_id; 1435 } else { 1436 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1437 } 1438 1439 mcp->out_mb = MBX_1|MBX_0; 1440 mcp->in_mb = MBX_0; 1441 mcp->timeout = MAILBOX_TOV; 1442 rval = ql_mailbox_command(ha, mcp); 1443 1444 if (rval != QL_SUCCESS) { 1445 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1446 } else { 1447 /*EMPTY*/ 1448 QL_PRINT_3(ha, "done\n"); 1449 } 1450 1451 return (rval); 1452 } 1453 1454 /* 1455 * ql_loop_port_enable 1456 * Issue loop port enable mailbox command. 1457 * 1458 * Input: 1459 * ha: adapter state pointer. 1460 * tq: target queue pointer. 1461 * 1462 * Returns: 1463 * ql local function return status code. 1464 * 1465 * Context: 1466 * Kernel context. 1467 */ 1468 int 1469 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq) 1470 { 1471 int rval; 1472 mbx_cmd_t mc = {0}; 1473 mbx_cmd_t *mcp = &mc; 1474 1475 QL_PRINT_3(ha, "started\n"); 1476 1477 mcp->mb[0] = MBC_LOOP_PORT_ENABLE; 1478 1479 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1480 mcp->mb[1] = tq->d_id.b.al_pa; 1481 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1482 mcp->mb[1] = tq->loop_id; 1483 } else { 1484 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 1485 } 1486 mcp->out_mb = MBX_1|MBX_0; 1487 mcp->in_mb = MBX_0; 1488 mcp->timeout = MAILBOX_TOV; 1489 rval = ql_mailbox_command(ha, mcp); 1490 1491 if (rval != QL_SUCCESS) { 1492 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 1493 } else { 1494 /*EMPTY*/ 1495 QL_PRINT_3(ha, "done\n"); 1496 } 1497 1498 return (rval); 1499 } 1500 1501 /* 1502 * ql_login_lport 1503 * Issue login loop port mailbox command. 1504 * 1505 * Input: 1506 * ha: adapter state pointer. 1507 * tq: target queue pointer. 1508 * loop_id: FC loop id. 1509 * opt: options. 1510 * LLF_NONE, LLF_PLOGI 1511 * 1512 * Returns: 1513 * ql local function return status code. 1514 * 1515 * Context: 1516 * Kernel context. 1517 */ 1518 int 1519 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1520 uint16_t opt) 1521 { 1522 int rval; 1523 uint16_t flags; 1524 ql_mbx_data_t mr; 1525 mbx_cmd_t mc = {0}; 1526 mbx_cmd_t *mcp = &mc; 1527 1528 QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n", 1529 ha->instance, tq->d_id.b24, loop_id); 1530 1531 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1532 flags = CF_CMD_PLOGI; 1533 if ((opt & LLF_PLOGI) == 0) { 1534 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1535 } 1536 rval = ql_log_iocb(ha, tq, loop_id, flags, &mr); 1537 } else { 1538 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 1539 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1540 mcp->mb[1] = loop_id; 1541 } else { 1542 mcp->mb[1] = (uint16_t)(loop_id << 8); 1543 } 1544 mcp->mb[2] = opt; 1545 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1546 mcp->in_mb = MBX_0; 1547 mcp->timeout = MAILBOX_TOV; 1548 rval = ql_mailbox_command(ha, mcp); 1549 } 1550 1551 if (rval != QL_SUCCESS) { 1552 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24, 1553 loop_id, rval); 1554 } else { 1555 /*EMPTY*/ 1556 QL_PRINT_3(ha, "done\n"); 1557 } 1558 1559 return (rval); 1560 } 1561 1562 /* 1563 * ql_login_fport 1564 * Issue login fabric port mailbox command. 1565 * 1566 * Input: 1567 * ha: adapter state pointer. 1568 * tq: target queue pointer. 1569 * loop_id: FC loop id. 1570 * opt: options. 1571 * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI 1572 * mr: pointer for mailbox data. 1573 * 1574 * Returns: 1575 * ql local function return status code. 1576 * 1577 * Context: 1578 * Kernel context. 1579 */ 1580 int 1581 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1582 uint16_t opt, ql_mbx_data_t *mr) 1583 { 1584 int rval; 1585 uint16_t flags; 1586 mbx_cmd_t mc = {0}; 1587 mbx_cmd_t *mcp = &mc; 1588 1589 QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n", 1590 ha->instance, tq->d_id.b24, loop_id); 1591 1592 if ((tq->d_id.b24 & QL_PORT_ID_MASK) == FS_MANAGEMENT_SERVER) { 1593 opt = (uint16_t)(opt | LFF_NO_PRLI); 1594 } 1595 1596 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1597 flags = CF_CMD_PLOGI; 1598 if (opt & LFF_NO_PLOGI) { 1599 flags = (uint16_t)(flags | CFO_COND_PLOGI); 1600 } 1601 if (opt & LFF_NO_PRLI) { 1602 flags = (uint16_t)(flags | CFO_SKIP_PRLI); 1603 } 1604 rval = ql_log_iocb(ha, tq, loop_id, flags, mr); 1605 } else { 1606 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1607 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1608 mcp->mb[1] = loop_id; 1609 mcp->mb[10] = opt; 1610 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 1611 } else { 1612 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 1613 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1614 } 1615 mcp->mb[2] = MSW(tq->d_id.b24); 1616 mcp->mb[3] = LSW(tq->d_id.b24); 1617 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 1618 mcp->timeout = MAILBOX_TOV; 1619 rval = ql_mailbox_command(ha, mcp); 1620 1621 /* Return mailbox data. */ 1622 if (mr != NULL) { 1623 mr->mb[0] = mcp->mb[0]; 1624 mr->mb[1] = mcp->mb[1]; 1625 mr->mb[2] = mcp->mb[2]; 1626 mr->mb[6] = mcp->mb[6]; 1627 mr->mb[7] = mcp->mb[7]; 1628 } 1629 } 1630 1631 if (rval != QL_SUCCESS) { 1632 EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, " 1633 "mb2=%04x\n", tq->d_id.b24, loop_id, rval, 1634 mr != NULL ? mr->mb[1] : mcp->mb[1], 1635 mr != NULL ? mr->mb[2] : mcp->mb[2]); 1636 } else { 1637 /*EMPTY*/ 1638 QL_PRINT_3(ha, "done\n"); 1639 } 1640 1641 return (rval); 1642 } 1643 1644 /* 1645 * ql_logout_fabric_port 1646 * Issue logout fabric port mailbox command. 1647 * 1648 * Input: 1649 * ha: adapter state pointer. 1650 * tq: target queue pointer. 1651 * 1652 * Returns: 1653 * ql local function return status code. 1654 * 1655 * Context: 1656 * Kernel context. 1657 */ 1658 int 1659 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq) 1660 { 1661 int rval; 1662 uint16_t flag; 1663 ql_mbx_data_t mr; 1664 mbx_cmd_t mc = {0}; 1665 mbx_cmd_t *mcp = &mc; 1666 1667 QL_PRINT_3(ha, "started, loop_id=%xh d_id=%xh\n", 1668 tq->loop_id, tq->d_id.b24); 1669 1670 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1671 if ((ha->topology & QL_N_PORT) && 1672 (tq->loop_id != 0x7fe) && 1673 (tq->loop_id != 0x7ff)) { 1674 flag = (uint16_t)(CFO_IMPLICIT_LOGO | 1675 CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE); 1676 1677 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr); 1678 } else { 1679 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1680 CFO_EXPLICIT_LOGO | CF_CMD_LOGO | 1681 CFO_FREE_N_PORT_HANDLE : 1682 CFO_IMPLICIT_LOGO | CF_CMD_LOGO | 1683 CFO_FREE_N_PORT_HANDLE); 1684 1685 rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr); 1686 } 1687 1688 if (rval == QL_SUCCESS) { 1689 EL(ha, "tq=%ph, loop_id=%xh, d_id=%xh, flag=%xh\n", 1690 tq, tq->loop_id, tq->d_id.b24, flag); 1691 } 1692 } else { 1693 flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0); 1694 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 1695 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1696 mcp->mb[1] = tq->loop_id; 1697 mcp->mb[10] = flag; 1698 mcp->out_mb = MBX_10|MBX_1|MBX_0; 1699 } else { 1700 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag); 1701 mcp->out_mb = MBX_1|MBX_0; 1702 } 1703 mcp->in_mb = MBX_0; 1704 mcp->timeout = MAILBOX_TOV; 1705 rval = ql_mailbox_command(ha, mcp); 1706 } 1707 1708 if (rval != QL_SUCCESS) { 1709 EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n", rval, 1710 tq->d_id.b24, tq->loop_id); 1711 } else { 1712 /*EMPTY*/ 1713 QL_PRINT_3(ha, "done\n"); 1714 } 1715 1716 return (rval); 1717 } 1718 1719 /* 1720 * ql_log_iocb 1721 * Function issues login/logout IOCB. 1722 * 1723 * Input: 1724 * ha: adapter state pointer. 1725 * tq: target queue pointer. 1726 * loop_id: FC Loop ID. 1727 * flags: control flags. 1728 * mr: pointer for mailbox data. 1729 * 1730 * Returns: 1731 * ql local function return status code. 1732 * 1733 * Context: 1734 * Kernel context. 1735 */ 1736 int 1737 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id, 1738 uint16_t flags, ql_mbx_data_t *mr) 1739 { 1740 ql_mbx_iocb_t *pkt; 1741 int rval; 1742 uint32_t pkt_size; 1743 1744 QL_PRINT_3(ha, "started\n"); 1745 1746 pkt_size = sizeof (ql_mbx_iocb_t); 1747 pkt = kmem_zalloc(pkt_size, KM_SLEEP); 1748 if (pkt == NULL) { 1749 EL(ha, "failed, kmem_zalloc\n"); 1750 return (QL_MEMORY_ALLOC_FAILED); 1751 } 1752 1753 pkt->log.entry_type = LOG_TYPE; 1754 pkt->log.entry_count = 1; 1755 pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id); 1756 pkt->log.control_flags = (uint16_t)LE_16(flags); 1757 pkt->log.port_id[0] = tq->d_id.b.al_pa; 1758 pkt->log.port_id[1] = tq->d_id.b.area; 1759 pkt->log.port_id[2] = tq->d_id.b.domain; 1760 pkt->log.vp_index = ha->vp_index; 1761 1762 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 1763 if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) { 1764 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 1765 pkt->log.entry_status, tq->d_id.b24); 1766 rval = QL_FUNCTION_PARAMETER_ERROR; 1767 } 1768 1769 if (rval == QL_SUCCESS) { 1770 if (pkt->log.rsp_size == 0xB) { 1771 LITTLE_ENDIAN_32(&pkt->log.io_param[5]); 1772 tq->cmn_features = MSW(pkt->log.io_param[5]); 1773 LITTLE_ENDIAN_32(&pkt->log.io_param[6]); 1774 tq->conc_sequences = MSW(pkt->log.io_param[6]); 1775 tq->relative_offset = LSW(pkt->log.io_param[6]); 1776 LITTLE_ENDIAN_32(&pkt->log.io_param[9]); 1777 tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]); 1778 tq->class3_conc_sequences = LSW(pkt->log.io_param[9]); 1779 LITTLE_ENDIAN_32(&pkt->log.io_param[10]); 1780 tq->class3_open_sequences_per_exch = 1781 MSW(pkt->log.io_param[10]); 1782 tq->prli_payload_length = 0x14; 1783 } 1784 if (mr != NULL) { 1785 LITTLE_ENDIAN_16(&pkt->log.status); 1786 LITTLE_ENDIAN_32(&pkt->log.io_param[0]); 1787 LITTLE_ENDIAN_32(&pkt->log.io_param[1]); 1788 1789 if (pkt->log.status != CS_COMPLETE) { 1790 EL(ha, "failed, status=%xh, iop0=%xh, iop1=" 1791 "%xh\n", pkt->log.status, 1792 pkt->log.io_param[0], 1793 pkt->log.io_param[1]); 1794 1795 switch (pkt->log.io_param[0]) { 1796 case CS0_NO_LINK: 1797 case CS0_FIRMWARE_NOT_READY: 1798 mr->mb[0] = MBS_COMMAND_ERROR; 1799 mr->mb[1] = 1; 1800 break; 1801 case CS0_NO_IOCB: 1802 case CS0_NO_PCB_ALLOCATED: 1803 mr->mb[0] = MBS_COMMAND_ERROR; 1804 mr->mb[1] = 2; 1805 break; 1806 case CS0_NO_EXCH_CTRL_BLK: 1807 mr->mb[0] = MBS_COMMAND_ERROR; 1808 mr->mb[1] = 3; 1809 break; 1810 case CS0_COMMAND_FAILED: 1811 mr->mb[0] = MBS_COMMAND_ERROR; 1812 mr->mb[1] = 4; 1813 switch (LSB(pkt->log.io_param[1])) { 1814 case CS1_PLOGI_RESPONSE_FAILED: 1815 mr->mb[2] = 3; 1816 break; 1817 case CS1_PRLI_FAILED: 1818 mr->mb[2] = 4; 1819 break; 1820 case CS1_PRLI_RESPONSE_FAILED: 1821 mr->mb[2] = 5; 1822 break; 1823 case CS1_COMMAND_LOGGED_OUT: 1824 mr->mb[2] = 7; 1825 break; 1826 case CS1_PLOGI_FAILED: 1827 default: 1828 EL(ha, "log iop1 = %xh\n", 1829 LSB(pkt->log.io_param[1])) 1830 mr->mb[2] = 2; 1831 break; 1832 } 1833 break; 1834 case CS0_PORT_NOT_LOGGED_IN: 1835 mr->mb[0] = MBS_COMMAND_ERROR; 1836 mr->mb[1] = 4; 1837 mr->mb[2] = 7; 1838 break; 1839 case CS0_NO_FLOGI_ACC: 1840 case CS0_NO_FABRIC_PRESENT: 1841 mr->mb[0] = MBS_COMMAND_ERROR; 1842 mr->mb[1] = 5; 1843 break; 1844 case CS0_ELS_REJECT_RECEIVED: 1845 mr->mb[0] = MBS_COMMAND_ERROR; 1846 mr->mb[1] = 0xd; 1847 break; 1848 case CS0_PORT_ID_USED: 1849 mr->mb[0] = MBS_PORT_ID_USED; 1850 mr->mb[1] = LSW(pkt->log.io_param[1]); 1851 break; 1852 case CS0_N_PORT_HANDLE_USED: 1853 mr->mb[0] = MBS_LOOP_ID_USED; 1854 mr->mb[1] = MSW(pkt->log.io_param[1]); 1855 mr->mb[2] = LSW(pkt->log.io_param[1]); 1856 break; 1857 case CS0_NO_N_PORT_HANDLE_AVAILABLE: 1858 mr->mb[0] = MBS_ALL_IDS_IN_USE; 1859 break; 1860 case CS0_CMD_PARAMETER_ERROR: 1861 default: 1862 EL(ha, "pkt->log iop[0]=%xh\n", 1863 pkt->log.io_param[0]); 1864 mr->mb[0] = 1865 MBS_COMMAND_PARAMETER_ERROR; 1866 break; 1867 } 1868 } else { 1869 QL_PRINT_3(ha, "status=%xh\n", pkt->log.status); 1870 1871 mr->mb[0] = MBS_COMMAND_COMPLETE; 1872 mr->mb[1] = (uint16_t) 1873 (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0); 1874 if (pkt->log.io_param[0] & BIT_8) { 1875 mr->mb[1] = (uint16_t) 1876 (mr->mb[1] | BIT_1); 1877 } 1878 } 1879 rval = mr->mb[0]; 1880 } 1881 1882 } 1883 1884 kmem_free(pkt, pkt_size); 1885 1886 if (rval != QL_SUCCESS) { 1887 EL(ha, "failed, rval=%xh, d_id=%xh loop_id=%xh\n", 1888 rval, tq->d_id.b24, loop_id); 1889 } else { 1890 /*EMPTY*/ 1891 QL_PRINT_3(ha, "done\n"); 1892 } 1893 1894 return (rval); 1895 } 1896 1897 /* 1898 * ql_get_port_database 1899 * Issue get port database mailbox command 1900 * and copy context to device queue. 1901 * 1902 * Input: 1903 * ha: adapter state pointer. 1904 * tq: target queue pointer. 1905 * opt: options. 1906 * PDF_NONE, PDF_PLOGI, PDF_ADISC 1907 * Returns: 1908 * ql local function return status code. 1909 * 1910 * Context: 1911 * Kernel context. 1912 */ 1913 int 1914 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt) 1915 { 1916 int rval; 1917 dma_mem_t mem_desc; 1918 mbx_cmd_t mc = {0}; 1919 mbx_cmd_t *mcp = &mc; 1920 port_database_23_t *pd23; 1921 1922 QL_PRINT_3(ha, "started\n"); 1923 1924 pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP); 1925 if (pd23 == NULL) { 1926 rval = QL_MEMORY_ALLOC_FAILED; 1927 EL(ha, "failed, rval = %xh\n", rval); 1928 return (rval); 1929 } 1930 1931 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 1932 PORT_DATABASE_SIZE)) != QL_SUCCESS) { 1933 return (QL_MEMORY_ALLOC_FAILED); 1934 } 1935 1936 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1937 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1938 mcp->mb[1] = tq->loop_id; 1939 mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area); 1940 mcp->mb[5] = (uint16_t)tq->d_id.b.domain; 1941 mcp->mb[9] = ha->vp_index; 1942 mcp->mb[10] = (uint16_t)(opt | PDF_ADISC); 1943 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3| 1944 MBX_2|MBX_1|MBX_0; 1945 } else { 1946 mcp->mb[0] = (uint16_t)(opt == PDF_NONE ? 1947 MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE); 1948 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1949 mcp->mb[1] = tq->loop_id; 1950 mcp->mb[10] = opt; 1951 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3| 1952 MBX_2|MBX_1|MBX_0; 1953 } else { 1954 mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt); 1955 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1956 } 1957 } 1958 1959 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 1960 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 1961 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 1962 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 1963 mcp->in_mb = MBX_0; 1964 mcp->timeout = MAILBOX_TOV; 1965 rval = ql_mailbox_command(ha, mcp); 1966 1967 if (rval == QL_SUCCESS) { 1968 ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23); 1969 } 1970 1971 ql_free_dma_resource(ha, &mem_desc); 1972 1973 if (rval == QL_SUCCESS) { 1974 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 1975 port_database_24_t *pd24 = (port_database_24_t *)pd23; 1976 1977 tq->master_state = pd24->current_login_state; 1978 tq->slave_state = pd24->last_stable_login_state; 1979 if (PD_PORT_LOGIN(tq)) { 1980 /* Names are big endian. */ 1981 bcopy((void *)&pd24->port_name[0], 1982 (void *)&tq->port_name[0], 8); 1983 bcopy((void *)&pd24->node_name[0], 1984 (void *)&tq->node_name[0], 8); 1985 tq->hard_addr.b.al_pa = pd24->hard_address[2]; 1986 tq->hard_addr.b.area = pd24->hard_address[1]; 1987 tq->hard_addr.b.domain = pd24->hard_address[0]; 1988 tq->class3_rcv_data_size = 1989 pd24->receive_data_size; 1990 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 1991 tq->prli_svc_param_word_0 = 1992 pd24->PRLI_service_parameter_word_0; 1993 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 1994 tq->prli_svc_param_word_3 = 1995 pd24->PRLI_service_parameter_word_3; 1996 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 1997 } 1998 } else { 1999 tq->master_state = pd23->master_state; 2000 tq->slave_state = pd23->slave_state; 2001 if (PD_PORT_LOGIN(tq)) { 2002 /* Names are big endian. */ 2003 bcopy((void *)&pd23->port_name[0], 2004 (void *)&tq->port_name[0], 8); 2005 bcopy((void *)&pd23->node_name[0], 2006 (void *)&tq->node_name[0], 8); 2007 tq->hard_addr.b.al_pa = pd23->hard_address[2]; 2008 tq->hard_addr.b.area = pd23->hard_address[1]; 2009 tq->hard_addr.b.domain = pd23->hard_address[0]; 2010 tq->cmn_features = pd23->common_features; 2011 LITTLE_ENDIAN_16(&tq->cmn_features); 2012 tq->conc_sequences = 2013 pd23->total_concurrent_sequences; 2014 LITTLE_ENDIAN_16(&tq->conc_sequences); 2015 tq->relative_offset = 2016 pd23->RO_by_information_category; 2017 LITTLE_ENDIAN_16(&tq->relative_offset); 2018 tq->class3_recipient_ctl = pd23->recipient; 2019 LITTLE_ENDIAN_16(&tq->class3_recipient_ctl); 2020 tq->class3_rcv_data_size = 2021 pd23->receive_data_size; 2022 LITTLE_ENDIAN_16(&tq->class3_rcv_data_size); 2023 tq->class3_conc_sequences = 2024 pd23->concurrent_sequences; 2025 LITTLE_ENDIAN_16(&tq->class3_conc_sequences); 2026 tq->class3_open_sequences_per_exch = 2027 pd23->open_sequences_per_exchange; 2028 LITTLE_ENDIAN_16( 2029 &tq->class3_open_sequences_per_exch); 2030 tq->prli_payload_length = 2031 pd23->PRLI_payload_length; 2032 LITTLE_ENDIAN_16(&tq->prli_payload_length); 2033 tq->prli_svc_param_word_0 = 2034 pd23->PRLI_service_parameter_word_0; 2035 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0); 2036 tq->prli_svc_param_word_3 = 2037 pd23->PRLI_service_parameter_word_3; 2038 LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3); 2039 } 2040 } 2041 2042 if (!PD_PORT_LOGIN(tq)) { 2043 EL(ha, "d_id=%xh, loop_id=%xh, not logged in " 2044 "master=%xh, slave=%xh\n", tq->d_id.b24, 2045 tq->loop_id, tq->master_state, tq->slave_state); 2046 rval = QL_NOT_LOGGED_IN; 2047 } else { 2048 tq->flags = tq->prli_svc_param_word_3 & 2049 PRLI_W3_TARGET_FUNCTION ? 2050 tq->flags & ~TQF_INITIATOR_DEVICE : 2051 tq->flags | TQF_INITIATOR_DEVICE; 2052 2053 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) { 2054 tq->flags = tq->prli_svc_param_word_3 & 2055 PRLI_W3_RETRY ? 2056 tq->flags | TQF_TAPE_DEVICE : 2057 tq->flags & ~TQF_TAPE_DEVICE; 2058 } else { 2059 tq->flags &= ~TQF_TAPE_DEVICE; 2060 } 2061 } 2062 } 2063 2064 kmem_free(pd23, PORT_DATABASE_SIZE); 2065 2066 /* 2067 * log the trace in any cases other than QL_SUCCESS. 2068 */ 2069 if (rval != QL_SUCCESS) { 2070 EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n", 2071 rval, tq->d_id.b24, tq->loop_id); 2072 } else { 2073 /*EMPTY*/ 2074 QL_PRINT_3(ha, "done\n"); 2075 } 2076 2077 return (rval); 2078 } 2079 2080 /* 2081 * ql_get_loop_position_map 2082 * Issue get loop position map mailbox command. 2083 * 2084 * Input: 2085 * ha: adapter state pointer. 2086 * size: size of data buffer. 2087 * bufp: data pointer for DMA data. 2088 * 2089 * Returns: 2090 * ql local function return status code. 2091 * 2092 * Context: 2093 * Kernel context. 2094 */ 2095 int 2096 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2097 { 2098 int rval; 2099 dma_mem_t mem_desc; 2100 mbx_cmd_t mc = {0}; 2101 mbx_cmd_t *mcp = &mc; 2102 2103 QL_PRINT_3(ha, "started\n"); 2104 2105 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2106 (uint32_t)size)) != QL_SUCCESS) { 2107 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2108 return (QL_MEMORY_ALLOC_FAILED); 2109 } 2110 2111 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 2112 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2113 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2114 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2115 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2116 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2117 mcp->in_mb = MBX_1|MBX_0; 2118 mcp->timeout = MAILBOX_TOV; 2119 rval = ql_mailbox_command(ha, mcp); 2120 2121 if (rval == QL_SUCCESS) { 2122 ql_get_mbox_dma_data(&mem_desc, bufp); 2123 } 2124 2125 ql_free_dma_resource(ha, &mem_desc); 2126 2127 if (rval != QL_SUCCESS) { 2128 EL(ha, "failed=%xh\n", rval); 2129 } else { 2130 /*EMPTY*/ 2131 QL_PRINT_3(ha, "done\n"); 2132 } 2133 2134 return (rval); 2135 } 2136 2137 /* 2138 * ql_set_rnid_params 2139 * Issue set RNID parameters mailbox command. 2140 * 2141 * Input: 2142 * ha: adapter state pointer. 2143 * size: size of data buffer. 2144 * bufp: data pointer for DMA data. 2145 * 2146 * Returns: 2147 * ql local function return status code. 2148 * 2149 * Context: 2150 * Kernel context. 2151 */ 2152 int 2153 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2154 { 2155 int rval; 2156 dma_mem_t mem_desc; 2157 mbx_cmd_t mc = {0}; 2158 mbx_cmd_t *mcp = &mc; 2159 2160 QL_PRINT_3(ha, "started\n"); 2161 2162 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp, 2163 (uint32_t)size)) != QL_SUCCESS) { 2164 EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval); 2165 return (rval); 2166 } 2167 2168 mcp->mb[0] = MBC_SET_PARAMETERS; 2169 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2170 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2171 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2172 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2173 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2174 mcp->in_mb = MBX_0; 2175 mcp->timeout = MAILBOX_TOV; 2176 rval = ql_mailbox_command(ha, mcp); 2177 2178 ql_free_dma_resource(ha, &mem_desc); 2179 2180 if (rval != QL_SUCCESS) { 2181 EL(ha, "failed, rval = %xh\n", rval); 2182 } else { 2183 /*EMPTY*/ 2184 QL_PRINT_3(ha, "done\n"); 2185 } 2186 2187 return (rval); 2188 } 2189 2190 /* 2191 * ql_send_rnid_els 2192 * Issue a send node identfication data mailbox command. 2193 * 2194 * Input: 2195 * ha: adapter state pointer. 2196 * loop_id: FC loop id. 2197 * opt: options. 2198 * size: size of data buffer. 2199 * bufp: data pointer for DMA data. 2200 * 2201 * Returns: 2202 * ql local function return status code. 2203 * 2204 * Context: 2205 * Kernel context. 2206 */ 2207 int 2208 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt, 2209 size_t size, caddr_t bufp) 2210 { 2211 int rval; 2212 dma_mem_t mem_desc; 2213 mbx_cmd_t mc = {0}; 2214 mbx_cmd_t *mcp = &mc; 2215 2216 QL_PRINT_3(ha, "started\n"); 2217 2218 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2219 (uint32_t)size)) != QL_SUCCESS) { 2220 return (QL_MEMORY_ALLOC_FAILED); 2221 } 2222 2223 mcp->mb[0] = MBC_SEND_RNID_ELS; 2224 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2225 mcp->mb[1] = loop_id; 2226 mcp->mb[9] = ha->vp_index; 2227 mcp->mb[10] = opt; 2228 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2229 } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2230 mcp->mb[1] = loop_id; 2231 mcp->mb[10] = opt; 2232 mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2233 } else { 2234 mcp->mb[1] = (uint16_t)(loop_id << 8 | opt); 2235 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2236 } 2237 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2238 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2239 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2240 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2241 mcp->in_mb = MBX_0; 2242 mcp->timeout = MAILBOX_TOV; 2243 rval = ql_mailbox_command(ha, mcp); 2244 2245 if (rval == QL_SUCCESS) { 2246 ql_get_mbox_dma_data(&mem_desc, bufp); 2247 } 2248 2249 ql_free_dma_resource(ha, &mem_desc); 2250 2251 if (rval != QL_SUCCESS) { 2252 EL(ha, "failed, rval = %xh\n", rval); 2253 } else { 2254 /*EMPTY*/ 2255 QL_PRINT_3(ha, "done\n"); 2256 } 2257 2258 return (rval); 2259 } 2260 2261 /* 2262 * ql_get_rnid_params 2263 * Issue get RNID parameters mailbox command. 2264 * 2265 * Input: 2266 * ha: adapter state pointer. 2267 * size: size of data buffer. 2268 * bufp: data pointer for DMA data. 2269 * 2270 * Returns: 2271 * ql local function return status code. 2272 * 2273 * Context: 2274 * Kernel context. 2275 */ 2276 int 2277 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 2278 { 2279 int rval; 2280 dma_mem_t mem_desc; 2281 mbx_cmd_t mc = {0}; 2282 mbx_cmd_t *mcp = &mc; 2283 2284 QL_PRINT_3(ha, "started\n"); 2285 2286 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2287 (uint32_t)size)) != QL_SUCCESS) { 2288 return (QL_MEMORY_ALLOC_FAILED); 2289 } 2290 2291 mcp->mb[0] = MBC_GET_PARAMETERS; 2292 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2293 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2294 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2295 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2296 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2297 mcp->in_mb = MBX_0; 2298 mcp->timeout = MAILBOX_TOV; 2299 rval = ql_mailbox_command(ha, mcp); 2300 2301 if (rval == QL_SUCCESS) { 2302 ql_get_mbox_dma_data(&mem_desc, bufp); 2303 } 2304 2305 ql_free_dma_resource(ha, &mem_desc); 2306 2307 if (rval != QL_SUCCESS) { 2308 EL(ha, "failed=%xh\n", rval); 2309 } else { 2310 /*EMPTY*/ 2311 QL_PRINT_3(ha, "done\n"); 2312 } 2313 2314 return (rval); 2315 } 2316 2317 /* 2318 * ql_get_link_status 2319 * Issue get link status mailbox command. 2320 * 2321 * Input: 2322 * ha: adapter state pointer. 2323 * loop_id: FC loop id or n_port_hdl. 2324 * size: size of data buffer. 2325 * bufp: data pointer for DMA data. 2326 * port_no: port number to query. 2327 * 2328 * Returns: 2329 * ql local function return status code. 2330 * 2331 * Context: 2332 * Kernel context. 2333 */ 2334 int 2335 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2336 caddr_t bufp, uint8_t port_no) 2337 { 2338 dma_mem_t mem_desc; 2339 mbx_cmd_t mc = {0}; 2340 mbx_cmd_t *mcp = &mc; 2341 int rval = QL_SUCCESS; 2342 int retry = 0; 2343 2344 QL_PRINT_3(ha, "started\n"); 2345 2346 do { 2347 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2348 (uint32_t)size)) != QL_SUCCESS) { 2349 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2350 return (QL_MEMORY_ALLOC_FAILED); 2351 } 2352 2353 mcp->mb[0] = MBC_GET_LINK_STATUS; 2354 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2355 if (loop_id == ha->loop_id) { 2356 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2357 mcp->mb[8] = (uint16_t)(size >> 2); 2358 mcp->out_mb = MBX_10|MBX_8; 2359 } else { 2360 mcp->mb[1] = loop_id; 2361 mcp->mb[4] = port_no; 2362 mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0); 2363 mcp->out_mb = MBX_10|MBX_4; 2364 } 2365 } else { 2366 if (retry) { 2367 port_no = (uint8_t)(port_no | BIT_3); 2368 } 2369 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2370 mcp->mb[1] = loop_id; 2371 mcp->mb[10] = port_no; 2372 mcp->out_mb = MBX_10; 2373 } else { 2374 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2375 port_no); 2376 mcp->out_mb = 0; 2377 } 2378 } 2379 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2380 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2381 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2382 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2383 mcp->in_mb = MBX_1|MBX_0; 2384 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2385 mcp->timeout = MAILBOX_TOV; 2386 2387 rval = ql_mailbox_command(ha, mcp); 2388 2389 if (rval == QL_SUCCESS) { 2390 ql_get_mbox_dma_data(&mem_desc, bufp); 2391 } 2392 2393 ql_free_dma_resource(ha, &mem_desc); 2394 2395 if (rval != QL_SUCCESS) { 2396 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2397 } 2398 2399 /* 2400 * Some of the devices want d_id in the payload, 2401 * strictly as per standard. Let's retry. 2402 */ 2403 2404 } while (rval == QL_COMMAND_ERROR && !retry++); 2405 2406 if (rval != QL_SUCCESS) { 2407 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 2408 } else { 2409 /*EMPTY*/ 2410 QL_PRINT_3(ha, "done\n"); 2411 } 2412 2413 return (rval); 2414 } 2415 2416 /* 2417 * ql_get_status_counts 2418 * Issue get adapter link status counts mailbox command. 2419 * 2420 * Input: 2421 * ha: adapter state pointer. 2422 * loop_id: FC loop id or n_port_hdl. 2423 * size: size of data buffer. 2424 * bufp: data pointer for DMA data. 2425 * port_no: port number to query. 2426 * 2427 * Returns: 2428 * ql local function return status code. 2429 * 2430 * Context: 2431 * Kernel context. 2432 */ 2433 int 2434 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size, 2435 caddr_t bufp, uint8_t port_no) 2436 { 2437 dma_mem_t mem_desc; 2438 mbx_cmd_t mc = {0}; 2439 mbx_cmd_t *mcp = &mc; 2440 int rval = QL_SUCCESS; 2441 2442 QL_PRINT_3(ha, "started\n"); 2443 2444 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2445 (uint32_t)size)) != QL_SUCCESS) { 2446 EL(ha, "setup_mbox_dma_resources failed: %x\n", rval); 2447 return (QL_MEMORY_ALLOC_FAILED); 2448 } 2449 2450 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2451 mcp->mb[0] = MBC_GET_STATUS_COUNTS; 2452 mcp->mb[8] = (uint16_t)(size / 4); 2453 mcp->out_mb = MBX_10|MBX_8; 2454 } else { 2455 mcp->mb[0] = MBC_GET_LINK_STATUS; 2456 2457 /* allows reporting when link is down */ 2458 if (CFG_IST(ha, CFG_CTRL_22XX) == 0) { 2459 port_no = (uint8_t)(port_no | BIT_6); 2460 } 2461 2462 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2463 mcp->mb[1] = loop_id; 2464 mcp->mb[10] = port_no; 2465 mcp->out_mb = MBX_10|MBX_1; 2466 } else { 2467 mcp->mb[1] = (uint16_t)((loop_id << 8) | 2468 port_no); 2469 mcp->out_mb = MBX_1; 2470 } 2471 } 2472 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2473 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2474 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2475 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2476 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2477 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2478 mcp->timeout = MAILBOX_TOV; 2479 rval = ql_mailbox_command(ha, mcp); 2480 2481 if (rval == QL_SUCCESS) { 2482 ql_get_mbox_dma_data(&mem_desc, bufp); 2483 } 2484 2485 ql_free_dma_resource(ha, &mem_desc); 2486 2487 if (rval != QL_SUCCESS) { 2488 EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval, 2489 mcp->mb[1], mcp->mb[2]); 2490 } else { 2491 /*EMPTY*/ 2492 QL_PRINT_3(ha, "done\n"); 2493 } 2494 2495 return (rval); 2496 } 2497 2498 /* 2499 * ql_reset_link_status 2500 * Issue Reset Link Error Status mailbox command 2501 * 2502 * Input: 2503 * ha: adapter state pointer. 2504 * 2505 * Returns: 2506 * ql local function return status code. 2507 * 2508 * Context: 2509 * Kernel context. 2510 */ 2511 int 2512 ql_reset_link_status(ql_adapter_state_t *ha) 2513 { 2514 int rval; 2515 mbx_cmd_t mc = {0}; 2516 mbx_cmd_t *mcp = &mc; 2517 2518 QL_PRINT_3(ha, "started\n"); 2519 2520 mcp->mb[0] = MBC_RESET_LINK_STATUS; 2521 mcp->out_mb = MBX_0; 2522 mcp->in_mb = MBX_0; 2523 mcp->timeout = MAILBOX_TOV; 2524 rval = ql_mailbox_command(ha, mcp); 2525 2526 if (rval != QL_SUCCESS) { 2527 EL(ha, "failed=%xh\n", rval); 2528 } else { 2529 /*EMPTY*/ 2530 QL_PRINT_3(ha, "done\n"); 2531 } 2532 2533 return (rval); 2534 } 2535 2536 /* 2537 * ql_loop_reset 2538 * Issue loop reset. 2539 * 2540 * Input: 2541 * ha: adapter state pointer. 2542 * 2543 * Returns: 2544 * ql local function return status code. 2545 * 2546 * Context: 2547 * Kernel context. 2548 */ 2549 int 2550 ql_loop_reset(ql_adapter_state_t *ha) 2551 { 2552 int rval; 2553 2554 QL_PRINT_3(ha, "started\n"); 2555 2556 if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) { 2557 rval = ql_lip_reset(ha, 0xff); 2558 } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) { 2559 rval = ql_full_login_lip(ha); 2560 } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) { 2561 rval = ql_target_reset(ha, NULL, ha->loop_reset_delay); 2562 } else { 2563 rval = ql_initiate_lip(ha); 2564 } 2565 2566 if (rval != QL_SUCCESS) { 2567 EL(ha, "failed, rval = %xh\n", rval); 2568 } else { 2569 /*EMPTY*/ 2570 QL_PRINT_3(ha, "done\n"); 2571 } 2572 2573 return (rval); 2574 } 2575 2576 /* 2577 * ql_initiate_lip 2578 * Initiate LIP mailbox command. 2579 * 2580 * Input: 2581 * ha: adapter state pointer. 2582 * 2583 * Returns: 2584 * ql local function return status code. 2585 * 2586 * Context: 2587 * Kernel context. 2588 */ 2589 int 2590 ql_initiate_lip(ql_adapter_state_t *ha) 2591 { 2592 int rval; 2593 mbx_cmd_t mc = {0}; 2594 mbx_cmd_t *mcp = &mc; 2595 2596 QL_PRINT_3(ha, "started\n"); 2597 2598 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) { 2599 ql_toggle_loop_state(ha); 2600 QL_PRINT_3(ha, "8081 done\n"); 2601 return (QL_SUCCESS); 2602 } 2603 if (CFG_IST(ha, CFG_FC_TYPE_2)) { 2604 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2605 mcp->mb[1] = BIT_4; 2606 mcp->mb[3] = ha->loop_reset_delay; 2607 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2608 } else { 2609 mcp->mb[0] = MBC_INITIATE_LIP; 2610 mcp->out_mb = MBX_0; 2611 } 2612 mcp->in_mb = MBX_0; 2613 mcp->timeout = MAILBOX_TOV; 2614 rval = ql_mailbox_command(ha, mcp); 2615 2616 if (rval != QL_SUCCESS) { 2617 EL(ha, "failed, rval = %xh\n", rval); 2618 } else { 2619 /*EMPTY*/ 2620 QL_PRINT_3(ha, "done\n"); 2621 } 2622 2623 return (rval); 2624 } 2625 2626 /* 2627 * ql_full_login_lip 2628 * Issue full login LIP mailbox command. 2629 * 2630 * Input: 2631 * ha: adapter state pointer. 2632 * 2633 * Returns: 2634 * ql local function return status code. 2635 * 2636 * Context: 2637 * Kernel context. 2638 */ 2639 int 2640 ql_full_login_lip(ql_adapter_state_t *ha) 2641 { 2642 int rval; 2643 mbx_cmd_t mc = {0}; 2644 mbx_cmd_t *mcp = &mc; 2645 2646 QL_PRINT_3(ha, "started\n"); 2647 2648 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) { 2649 ql_toggle_loop_state(ha); 2650 QL_PRINT_3(ha, "8081 done\n"); 2651 return (QL_SUCCESS); 2652 } 2653 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2654 if (CFG_IST(ha, CFG_FC_TYPE_2)) { 2655 mcp->mb[1] = BIT_3; 2656 } 2657 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2658 mcp->in_mb = MBX_0; 2659 mcp->timeout = MAILBOX_TOV; 2660 rval = ql_mailbox_command(ha, mcp); 2661 2662 if (rval != QL_SUCCESS) { 2663 EL(ha, "failed, rval = %xh\n", rval); 2664 } else { 2665 /*EMPTY*/ 2666 QL_PRINT_3(ha, "done"); 2667 } 2668 2669 return (rval); 2670 } 2671 2672 /* 2673 * ql_lip_reset 2674 * Issue lip reset to a port. 2675 * 2676 * Input: 2677 * ha: adapter state pointer. 2678 * loop_id: FC loop id. 2679 * 2680 * Returns: 2681 * ql local function return status code. 2682 * 2683 * Context: 2684 * Kernel context. 2685 */ 2686 int 2687 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id) 2688 { 2689 int rval; 2690 mbx_cmd_t mc = {0}; 2691 mbx_cmd_t *mcp = &mc; 2692 2693 QL_PRINT_3(ha, "started\n"); 2694 2695 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) { 2696 ql_toggle_loop_state(ha); 2697 QL_PRINT_3(ha, "8081 done\n"); 2698 return (QL_SUCCESS); 2699 } 2700 2701 if (CFG_IST(ha, CFG_FC_TYPE_2)) { 2702 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2703 mcp->mb[1] = BIT_6; 2704 mcp->mb[3] = ha->loop_reset_delay; 2705 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2706 } else { 2707 mcp->mb[0] = MBC_LIP_RESET; 2708 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2709 mcp->mb[1] = loop_id; 2710 mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0; 2711 } else { 2712 mcp->mb[1] = (uint16_t)(loop_id << 8); 2713 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2714 } 2715 mcp->mb[2] = ha->loop_reset_delay; 2716 } 2717 mcp->in_mb = MBX_0; 2718 mcp->timeout = MAILBOX_TOV; 2719 rval = ql_mailbox_command(ha, mcp); 2720 2721 if (rval != QL_SUCCESS) { 2722 EL(ha, "failed, rval = %xh\n", rval); 2723 } else { 2724 /*EMPTY*/ 2725 QL_PRINT_3(ha, "done\n"); 2726 } 2727 2728 return (rval); 2729 } 2730 2731 /* 2732 * ql_abort_command 2733 * Abort command aborts a specified IOCB. 2734 * 2735 * Input: 2736 * ha: adapter state pointer. 2737 * sp: SRB structure pointer. 2738 * 2739 * Returns: 2740 * ql local function return status code. 2741 * 2742 * Context: 2743 * Kernel context. 2744 */ 2745 int 2746 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp) 2747 { 2748 int rval; 2749 mbx_cmd_t mc = {0}; 2750 mbx_cmd_t *mcp = &mc; 2751 ql_tgt_t *tq = sp->lun_queue->target_queue; 2752 2753 QL_PRINT_3(ha, "started\n"); 2754 2755 sp->flags |= SRB_ABORTING; 2756 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2757 rval = ql_abort_cmd_iocb(ha, sp); 2758 } else { 2759 mcp->mb[0] = MBC_ABORT_COMMAND_IOCB; 2760 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 2761 mcp->mb[1] = tq->loop_id; 2762 } else { 2763 mcp->mb[1] = (uint16_t)(tq->loop_id << 8); 2764 } 2765 mcp->mb[2] = LSW(sp->handle); 2766 mcp->mb[3] = MSW(sp->handle); 2767 mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ? 2768 sp->lun_queue->lun_no : 0); 2769 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2770 mcp->in_mb = MBX_0; 2771 mcp->timeout = MAILBOX_TOV; 2772 rval = ql_mailbox_command(ha, mcp); 2773 } 2774 2775 if (rval != QL_SUCCESS) { 2776 EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval, 2777 tq->d_id.b24, sp->handle); 2778 } else { 2779 /*EMPTY*/ 2780 QL_PRINT_3(ha, "done\n"); 2781 } 2782 2783 return (rval); 2784 } 2785 2786 /* 2787 * ql_abort_cmd_iocb 2788 * Function issues abort command IOCB. 2789 * 2790 * Input: 2791 * ha: adapter state pointer. 2792 * sp: SRB structure pointer. 2793 * 2794 * Returns: 2795 * ql local function return status code. 2796 * 2797 * Context: 2798 * Interrupt or Kernel context, no mailbox commands allowed. 2799 */ 2800 static int 2801 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp) 2802 { 2803 ql_mbx_iocb_t *pkt; 2804 int rval; 2805 uint32_t pkt_size; 2806 uint16_t comp_status; 2807 ql_tgt_t *tq = sp->lun_queue->target_queue; 2808 2809 QL_PRINT_3(ha, "started\n"); 2810 2811 pkt_size = sizeof (ql_mbx_iocb_t); 2812 if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) { 2813 EL(ha, "failed, kmem_zalloc\n"); 2814 return (QL_MEMORY_ALLOC_FAILED); 2815 } 2816 2817 pkt->abo.entry_type = ABORT_CMD_TYPE; 2818 pkt->abo.entry_count = 1; 2819 pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id); 2820 if (!CFG_IST(ha, CFG_CTRL_82XX)) { 2821 pkt->abo.options = AF_NO_ABTS; 2822 } 2823 pkt->abo.cmd_handle = LE_32(sp->handle); 2824 pkt->abo.target_id[0] = tq->d_id.b.al_pa; 2825 pkt->abo.target_id[1] = tq->d_id.b.area; 2826 pkt->abo.target_id[2] = tq->d_id.b.domain; 2827 pkt->abo.vp_index = ha->vp_index; 2828 2829 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size); 2830 2831 if (rval == QL_SUCCESS) { 2832 if ((pkt->abo.entry_status & 0x3c) != 0) { 2833 EL(ha, "failed, entry_status=%xh, d_id=%xh\n", 2834 pkt->abo.entry_status, tq->d_id.b24); 2835 rval = QL_FUNCTION_PARAMETER_ERROR; 2836 } else { 2837 comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl); 2838 if (comp_status != CS_COMPLETE) { 2839 EL(ha, "failed, comp_status=%xh, d_id=%xh\n", 2840 comp_status, tq->d_id.b24); 2841 rval = QL_FUNCTION_FAILED; 2842 } 2843 } 2844 } 2845 2846 kmem_free(pkt, pkt_size); 2847 2848 if (rval != QL_SUCCESS) { 2849 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 2850 } else { 2851 /*EMPTY*/ 2852 QL_PRINT_3(ha, "done\n"); 2853 } 2854 2855 return (rval); 2856 } 2857 2858 /* 2859 * ql_verify_checksum 2860 * Verify loaded RISC firmware. 2861 * 2862 * Input: 2863 * ha = adapter state pointer. 2864 * 2865 * Returns: 2866 * ql local function return status code. 2867 * 2868 * Context: 2869 * Kernel context. 2870 */ 2871 int 2872 ql_verify_checksum(ql_adapter_state_t *ha) 2873 { 2874 int rval; 2875 mbx_cmd_t mc = {0}; 2876 mbx_cmd_t *mcp = &mc; 2877 2878 QL_PRINT_3(ha, "started\n"); 2879 2880 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 2881 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2882 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 2883 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 2884 } else { 2885 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 2886 } 2887 mcp->out_mb = MBX_2|MBX_1|MBX_0; 2888 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2889 mcp->timeout = MAILBOX_TOV; 2890 rval = ql_mailbox_command(ha, mcp); 2891 2892 if (rval != QL_SUCCESS) { 2893 EL(ha, "failed, rval = %xh\n", rval); 2894 } else { 2895 /*EMPTY*/ 2896 QL_PRINT_3(ha, "done\n"); 2897 } 2898 2899 return (rval); 2900 } 2901 2902 /* 2903 * ql_get_id_list 2904 * Get d_id and loop ID list. 2905 * 2906 * Input: 2907 * ha: adapter state pointer. 2908 * bp: data pointer for DMA data. 2909 * size: size of data buffer. 2910 * mr: pointer for mailbox data. 2911 * 2912 * Returns: 2913 * ql local function return status code. 2914 * 2915 * Context: 2916 * Kernel context. 2917 */ 2918 int 2919 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, 2920 ql_mbx_data_t *mr) 2921 { 2922 int rval; 2923 dma_mem_t mem_desc; 2924 mbx_cmd_t mc = {0}; 2925 mbx_cmd_t *mcp = &mc; 2926 2927 QL_PRINT_3(ha, "started\n"); 2928 2929 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 2930 (uint32_t)size)) != QL_SUCCESS) { 2931 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 2932 return (QL_MEMORY_ALLOC_FAILED); 2933 } 2934 2935 mcp->mb[0] = MBC_GET_ID_LIST; 2936 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 2937 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2938 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2939 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2940 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2941 mcp->mb[8] = (uint16_t)size; 2942 mcp->mb[9] = ha->vp_index; 2943 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2944 } else { 2945 mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 2946 mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 2947 mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 2948 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 2949 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2950 } 2951 mcp->in_mb = MBX_1|MBX_0; 2952 mcp->timeout = MAILBOX_TOV; 2953 rval = ql_mailbox_command(ha, mcp); 2954 2955 if (rval == QL_SUCCESS) { 2956 ql_get_mbox_dma_data(&mem_desc, bp); 2957 } 2958 2959 ql_free_dma_resource(ha, &mem_desc); 2960 2961 /* Return mailbox data. */ 2962 if (mr != NULL) { 2963 mr->mb[0] = mcp->mb[0]; 2964 mr->mb[1] = mcp->mb[1]; 2965 } 2966 2967 if (rval != QL_SUCCESS) { 2968 EL(ha, "failed, rval = %xh\n", rval); 2969 } else { 2970 /*EMPTY*/ 2971 QL_PRINT_3(ha, "done\n"); 2972 } 2973 2974 return (rval); 2975 } 2976 2977 /* 2978 * ql_wrt_risc_ram 2979 * Load RISC RAM. 2980 * 2981 * Input: 2982 * ha: adapter state pointer. 2983 * risc_address: risc ram word address. 2984 * bp: DMA pointer. 2985 * word_count: 16/32bit word count. 2986 * 2987 * Returns: 2988 * ql local function return status code. 2989 * 2990 * Context: 2991 * Kernel context. 2992 */ 2993 int 2994 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 2995 uint32_t word_count) 2996 { 2997 int rval; 2998 mbx_cmd_t mc = {0}; 2999 mbx_cmd_t *mcp = &mc; 3000 3001 QL_PRINT_3(ha, "started\n"); 3002 3003 mcp->mb[1] = LSW(risc_address); 3004 mcp->mb[2] = MSW(LSD(bp)); 3005 mcp->mb[3] = LSW(LSD(bp)); 3006 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 3007 mcp->mb[0] = MBC_LOAD_RAM_EXTENDED; 3008 mcp->mb[4] = MSW(word_count); 3009 mcp->mb[5] = LSW(word_count); 3010 mcp->mb[8] = MSW(risc_address); 3011 mcp->out_mb = MBX_0_THRU_8; 3012 } else { 3013 mcp->mb[0] = MBC_LOAD_RISC_RAM; 3014 mcp->mb[4] = LSW(word_count); 3015 mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3016 } 3017 mcp->mb[6] = MSW(MSD(bp)); 3018 mcp->mb[7] = LSW(MSD(bp)); 3019 mcp->in_mb = MBX_0; 3020 mcp->timeout = MAILBOX_TOV; 3021 rval = ql_mailbox_command(ha, mcp); 3022 3023 if (rval != QL_SUCCESS) { 3024 EL(ha, "failed, rval = %xh\n", rval); 3025 } else { 3026 /*EMPTY*/ 3027 QL_PRINT_3(ha, "done\n"); 3028 } 3029 3030 return (rval); 3031 } 3032 3033 /* 3034 * ql_rd_risc_ram 3035 * Get RISC RAM. 3036 * 3037 * Input: 3038 * ha: adapter state pointer. 3039 * risc_address: risc ram word address. 3040 * bp: direct data pointer. 3041 * word_count: 16/32bit word count. 3042 * 3043 * Returns: 3044 * ql local function return status code. 3045 * 3046 * Context: 3047 * Kernel context. 3048 */ 3049 int 3050 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp, 3051 uint32_t word_count) 3052 { 3053 int rval; 3054 mbx_cmd_t mc = {0}; 3055 mbx_cmd_t *mcp = &mc; 3056 3057 QL_PRINT_3(ha, "started\n"); 3058 3059 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 3060 mcp->mb[0] = MBC_DUMP_RAM_EXTENDED; 3061 mcp->mb[1] = LSW(risc_address); 3062 mcp->mb[2] = MSW(LSD(bp)); 3063 mcp->mb[3] = LSW(LSD(bp)); 3064 mcp->mb[4] = MSW(word_count); 3065 mcp->mb[5] = LSW(word_count); 3066 mcp->mb[6] = MSW(MSD(bp)); 3067 mcp->mb[7] = LSW(MSD(bp)); 3068 mcp->mb[8] = MSW(risc_address); 3069 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 3070 MBX_0; 3071 } else { 3072 mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */ 3073 mcp->mb[1] = LSW(risc_address); 3074 mcp->mb[2] = MSW(LSD(bp)); 3075 mcp->mb[3] = LSW(LSD(bp)); 3076 mcp->mb[4] = LSW(word_count); 3077 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3078 } 3079 mcp->in_mb = MBX_0; 3080 mcp->timeout = MAILBOX_TOV; 3081 rval = ql_mailbox_command(ha, mcp); 3082 3083 if (rval != QL_SUCCESS) { 3084 EL(ha, "failed, rval = %xh\n", rval); 3085 } else { 3086 /*EMPTY*/ 3087 QL_PRINT_3(ha, "done\n"); 3088 } 3089 3090 return (rval); 3091 } 3092 3093 /* 3094 * ql_wrt_risc_ram_word 3095 * Write RISC RAM word. 3096 * 3097 * Input: 3098 * ha: adapter state pointer. 3099 * risc_address: risc ram word address. 3100 * data: data. 3101 * 3102 * Returns: 3103 * ql local function return status code. 3104 * 3105 * Context: 3106 * Kernel context. 3107 */ 3108 int 3109 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address, 3110 uint32_t data) 3111 { 3112 int rval; 3113 mbx_cmd_t mc = {0}; 3114 mbx_cmd_t *mcp = &mc; 3115 3116 QL_PRINT_3(ha, "started\n"); 3117 3118 mcp->mb[0] = MBC_WRITE_RAM_EXTENDED; 3119 mcp->mb[1] = LSW(risc_address); 3120 mcp->mb[2] = LSW(data); 3121 mcp->mb[3] = MSW(data); 3122 mcp->mb[8] = MSW(risc_address); 3123 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; 3124 mcp->in_mb = MBX_0; 3125 mcp->timeout = MAILBOX_TOV; 3126 3127 rval = ql_mailbox_command(ha, mcp); 3128 3129 if (rval != QL_SUCCESS) { 3130 EL(ha, "failed, rval = %xh\n", rval); 3131 } else { 3132 /*EMPTY*/ 3133 QL_PRINT_3(ha, "done\n"); 3134 } 3135 3136 return (rval); 3137 } 3138 3139 /* 3140 * ql_rd_risc_ram_word 3141 * Read RISC RAM word. 3142 * 3143 * Input: 3144 * ha: adapter state pointer. 3145 * risc_address: risc ram word address. 3146 * data: data pointer. 3147 * 3148 * Returns: 3149 * ql local function return status code. 3150 * 3151 * Context: 3152 * Kernel context. 3153 */ 3154 int 3155 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address, 3156 uint32_t *data) 3157 { 3158 int rval; 3159 mbx_cmd_t mc = {0}; 3160 mbx_cmd_t *mcp = &mc; 3161 3162 QL_PRINT_3(ha, "started\n"); 3163 3164 mcp->mb[0] = MBC_READ_RAM_EXTENDED; 3165 mcp->mb[1] = LSW(risc_address); 3166 mcp->mb[8] = MSW(risc_address); 3167 mcp->out_mb = MBX_8|MBX_1|MBX_0; 3168 mcp->in_mb = MBX_3|MBX_2|MBX_0; 3169 mcp->timeout = MAILBOX_TOV; 3170 3171 rval = ql_mailbox_command(ha, mcp); 3172 3173 if (rval != QL_SUCCESS) { 3174 EL(ha, "failed, rval = %xh\n", rval); 3175 } else { 3176 *data = mcp->mb[2]; 3177 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 3178 *data |= mcp->mb[3] << 16; 3179 } 3180 QL_PRINT_3(ha, "done\n"); 3181 } 3182 3183 return (rval); 3184 } 3185 3186 /* 3187 * ql_issue_mbx_iocb 3188 * Issue IOCB using mailbox command 3189 * 3190 * Input: 3191 * ha: adapter state pointer. 3192 * bp: buffer pointer. 3193 * size: buffer size. 3194 * 3195 * Returns: 3196 * ql local function return status code. 3197 * 3198 * Context: 3199 * Kernel context. 3200 */ 3201 int 3202 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size) 3203 { 3204 int rval; 3205 dma_mem_t mem_desc; 3206 mbx_cmd_t mc = {0}; 3207 mbx_cmd_t *mcp = &mc; 3208 3209 QL_PRINT_3(ha, "started\n"); 3210 3211 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3212 QL_SUCCESS) { 3213 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3214 return (rval); 3215 } 3216 3217 mcp->mb[0] = MBC_EXECUTE_IOCB; 3218 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3219 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3220 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3221 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3222 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 3223 mcp->in_mb = MBX_1|MBX_0; 3224 mcp->timeout = MAILBOX_TOV + 5; 3225 rval = ql_mailbox_command(ha, mcp); 3226 3227 if (rval == QL_SUCCESS) { 3228 ql_get_mbox_dma_data(&mem_desc, bp); 3229 } 3230 3231 ql_free_dma_resource(ha, &mem_desc); 3232 3233 if (rval != QL_SUCCESS) { 3234 EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 3235 } else { 3236 /*EMPTY*/ 3237 QL_PRINT_3(ha, "done\n"); 3238 } 3239 3240 return (rval); 3241 } 3242 3243 /* 3244 * ql_mbx_wrap_test 3245 * Mailbox register wrap test. 3246 * 3247 * Input: 3248 * ha: adapter state pointer. 3249 * mr: pointer for in/out mailbox data. 3250 * 3251 * Returns: 3252 * ql local function return status code. 3253 * 3254 * Context: 3255 * Kernel context. 3256 */ 3257 int 3258 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3259 { 3260 int rval; 3261 mbx_cmd_t mc = {0}; 3262 mbx_cmd_t *mcp = &mc; 3263 3264 QL_PRINT_3(ha, "started cfg=0x%llx\n", ha->cfg_flags); 3265 3266 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 3267 if (mr == NULL) { 3268 mcp->mb[1] = 0xAAAA; 3269 mcp->mb[2] = 0x5555; 3270 mcp->mb[3] = 0xAA55; 3271 mcp->mb[4] = 0x55AA; 3272 mcp->mb[5] = 0xA5A5; 3273 mcp->mb[6] = 0x5A5A; 3274 mcp->mb[7] = 0x2525; 3275 } else { 3276 mcp->mb[1] = mr->mb[1]; 3277 mcp->mb[2] = mr->mb[2]; 3278 mcp->mb[3] = mr->mb[3]; 3279 mcp->mb[4] = mr->mb[4]; 3280 mcp->mb[5] = mr->mb[5]; 3281 mcp->mb[6] = mr->mb[6]; 3282 mcp->mb[7] = mr->mb[7]; 3283 } 3284 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3285 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3286 mcp->timeout = MAILBOX_TOV; 3287 rval = ql_mailbox_command(ha, mcp); 3288 if (rval == QL_SUCCESS) { 3289 if (mr == NULL) { 3290 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 || 3291 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) { 3292 rval = QL_FUNCTION_FAILED; 3293 } 3294 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || 3295 mcp->mb[7] != 0x2525) { 3296 rval = QL_FUNCTION_FAILED; 3297 } 3298 } else { 3299 if (mcp->mb[1] != mr->mb[1] || 3300 mcp->mb[2] != mr->mb[2] || 3301 mcp->mb[3] != mr->mb[3] || 3302 mcp->mb[4] != mr->mb[4]) { 3303 rval = QL_FUNCTION_FAILED; 3304 } 3305 if (mcp->mb[5] != mr->mb[5] || 3306 mcp->mb[6] != mr->mb[6] || 3307 mcp->mb[7] != mr->mb[7]) { 3308 rval = QL_FUNCTION_FAILED; 3309 } 3310 } 3311 } 3312 3313 if (rval != QL_SUCCESS) { 3314 EL(ha, "failed=%xh\n", rval); 3315 } else { 3316 /*EMPTY*/ 3317 QL_PRINT_3(ha, "done\n"); 3318 } 3319 3320 return (rval); 3321 } 3322 3323 /* 3324 * ql_execute_fw 3325 * Start adapter firmware. 3326 * 3327 * Input: 3328 * ha: adapter state pointer. 3329 * 3330 * Returns: 3331 * ql local function return status code. 3332 * 3333 * Context: 3334 * Kernel context. 3335 */ 3336 int 3337 ql_execute_fw(ql_adapter_state_t *ha) 3338 { 3339 int rval; 3340 mbx_cmd_t mc = {0}; 3341 mbx_cmd_t *mcp = &mc; 3342 3343 QL_PRINT_3(ha, "started\n"); 3344 3345 if (CFG_IST(ha, CFG_CTRL_82XX)) { 3346 return (QL_SUCCESS); 3347 } 3348 3349 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 3350 if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 3351 mcp->mb[1] = MSW(ha->risc_fw[0].addr); 3352 mcp->mb[2] = LSW(ha->risc_fw[0].addr); 3353 } else { 3354 mcp->mb[1] = LSW(ha->risc_fw[0].addr); 3355 } 3356 if (CFG_IST(ha, CFG_LR_SUPPORT)) { 3357 mcp->mb[4] = BIT_0; 3358 } 3359 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3360 mcp->in_mb = MBX_0; 3361 mcp->timeout = MAILBOX_TOV; 3362 rval = ql_mailbox_command(ha, mcp); 3363 3364 if (CFG_IST(ha, CFG_CTRL_22XX)) { 3365 rval = QL_SUCCESS; 3366 } 3367 3368 if (rval != QL_SUCCESS) { 3369 EL(ha, "failed=%xh\n", rval); 3370 } else { 3371 /*EMPTY*/ 3372 QL_PRINT_3(ha, "done\n"); 3373 } 3374 3375 return (rval); 3376 } 3377 3378 /* 3379 * ql_get_firmware_option 3380 * Get Firmware Options Mailbox Command. 3381 * 3382 * Input: 3383 * ha: adapter state pointer. 3384 * mr: pointer for mailbox data. 3385 * 3386 * Returns: 3387 * ql local function return status code. 3388 * 3389 * Context: 3390 * Kernel context. 3391 */ 3392 int 3393 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3394 { 3395 int rval; 3396 mbx_cmd_t mc = {0}; 3397 mbx_cmd_t *mcp = &mc; 3398 3399 QL_PRINT_3(ha, "started\n"); 3400 3401 mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS; 3402 mcp->out_mb = MBX_0; 3403 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3404 mcp->timeout = MAILBOX_TOV; 3405 rval = ql_mailbox_command(ha, mcp); 3406 3407 /* Return mailbox data. */ 3408 if (mr != NULL) { 3409 mr->mb[0] = mcp->mb[0]; 3410 mr->mb[1] = mcp->mb[1]; 3411 mr->mb[2] = mcp->mb[2]; 3412 mr->mb[3] = mcp->mb[3]; 3413 } 3414 3415 if (rval != QL_SUCCESS) { 3416 EL(ha, "failed=%xh\n", rval); 3417 } else { 3418 /*EMPTY*/ 3419 QL_PRINT_9(ha, "done\n"); 3420 } 3421 3422 return (rval); 3423 } 3424 3425 /* 3426 * ql_set_firmware_option 3427 * Set Firmware Options Mailbox Command. 3428 * 3429 * Input: 3430 * ha: adapter state pointer. 3431 * mr: pointer for mailbox data. 3432 * 3433 * Returns: 3434 * ql local function return status code. 3435 * 3436 * Context: 3437 * Kernel context. 3438 */ 3439 int 3440 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3441 { 3442 int rval; 3443 mbx_cmd_t mc = {0}; 3444 mbx_cmd_t *mcp = &mc; 3445 3446 QL_PRINT_3(ha, "started\n"); 3447 3448 if (mr != NULL) { 3449 mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS; 3450 mcp->mb[1] = mr->mb[1]; 3451 mcp->mb[2] = mr->mb[2]; 3452 mcp->mb[3] = mr->mb[3]; 3453 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3454 mcp->in_mb = MBX_0; 3455 mcp->timeout = MAILBOX_TOV; 3456 rval = ql_mailbox_command(ha, mcp); 3457 } else { 3458 rval = QL_FUNCTION_PARAMETER_ERROR; 3459 } 3460 3461 if (rval != QL_SUCCESS) { 3462 EL(ha, "failed=%xh\n", rval); 3463 } else { 3464 /*EMPTY*/ 3465 QL_PRINT_3(ha, "done\n"); 3466 } 3467 3468 return (rval); 3469 } 3470 3471 /* 3472 * ql_init_firmware 3473 * Initialize firmware mailbox command. 3474 * 3475 * Input: 3476 * ha: adapter state pointer. 3477 * ha->init_ctrl_blk = setup for transmit. 3478 * 3479 * Returns: 3480 * ql local function return status code. 3481 * 3482 * Context: 3483 * Kernel context. 3484 */ 3485 int 3486 ql_init_firmware(ql_adapter_state_t *ha) 3487 { 3488 int rval; 3489 dma_mem_t mem_desc; 3490 mbx_cmd_t mc = {0}; 3491 mbx_cmd_t *mcp = &mc; 3492 3493 QL_PRINT_3(ha, "started\n"); 3494 3495 if (ha->flags & MULTI_QUEUE) { 3496 WR32_MBAR_REG(ha, ha->req_q[0]->mbar_req_in, 0); 3497 WR32_MBAR_REG(ha, ha->rsp_queues[0]->mbar_rsp_out, 0); 3498 } else if (CFG_IST(ha, CFG_CTRL_82XX)) { 3499 ql_8021_wr_req_in(ha, 0); 3500 WRT32_IO_REG(ha, req_out, 0); 3501 WRT32_IO_REG(ha, resp_in, 0); 3502 WRT32_IO_REG(ha, resp_out, 0); 3503 } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { 3504 WRT32_IO_REG(ha, req_in, 0); 3505 WRT32_IO_REG(ha, resp_out, 0); 3506 WRT32_IO_REG(ha, pri_req_in, 0); 3507 WRT32_IO_REG(ha, atio_req_out, 0); 3508 } else { 3509 WRT16_IO_REG(ha, req_in, 0); 3510 WRT16_IO_REG(ha, resp_out, 0); 3511 } 3512 if (ha->req_q[0]->req_out_shadow_ptr) { 3513 *ha->req_q[0]->req_out_shadow_ptr = 0; 3514 } 3515 if (ha->rsp_queues[0]->rsp_in_shadow_ptr) { 3516 *ha->rsp_queues[0]->rsp_in_shadow_ptr = 0; 3517 } 3518 3519 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, 3520 (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) != 3521 QL_SUCCESS) { 3522 EL(ha, "dma setup failed=%xh\n", rval); 3523 return (rval); 3524 } 3525 3526 mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ? 3527 MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE); 3528 3529 if (CFG_IST(ha, CFG_SBUS_CARD)) { 3530 mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_22XX) ? 3531 0x204c : 0x52); 3532 } 3533 3534 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3535 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3536 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3537 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3538 if (CFG_IST(ha, CFG_FCOE_SUPPORT)) { 3539 uint64_t ofst, addr; 3540 ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *) 3541 &ha->init_ctrl_blk.cb24; 3542 3543 mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW; 3544 if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) { 3545 ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb; 3546 addr = mem_desc.cookie.dmac_laddress + ofst; 3547 mcp->mb[10] = MSW(LSD(addr)); 3548 mcp->mb[11] = LSW(LSD(addr)); 3549 mcp->mb[12] = MSW(MSD(addr)); 3550 mcp->mb[13] = LSW(MSD(addr)); 3551 mcp->mb[14] = sizeof (ql_ext_icb_8100_t); 3552 mcp->mb[1] = BIT_0; 3553 } 3554 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6| 3555 MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3556 } else { 3557 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3558 } 3559 mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0; 3560 mcp->timeout = MAILBOX_TOV; 3561 rval = ql_mailbox_command(ha, mcp); 3562 3563 if (rval == QL_SUCCESS) { 3564 ha->sfp_stat = mcp->mb[2]; 3565 if (CFG_IST(ha, CFG_CTRL_82XX)) { 3566 (void) ql_8021_get_md_template(ha); 3567 } else { 3568 uint16_t i, opt; 3569 3570 opt = ha->flags & NO_INTR_HANDSHAKE ? 3571 IMO_NONE : IMO_INTERRUPT_HANDSHAKE; 3572 if (ha->flags & QUEUE_SHADOW_PTRS) { 3573 opt |= IMO_QUEUE_POINTER_SHADOWING; 3574 } 3575 /* Initialize ha multi-response-queue request queue */ 3576 if (ha->rsp_queues_cnt > 1) { 3577 rval = ql_init_req_q(ha, ha->req_q[1], opt); 3578 if (rval != QL_SUCCESS) { 3579 EL(ha, "ql_init_req_q=%xh\n", rval); 3580 return (rval); 3581 } 3582 } 3583 /* Initialize multi-response queues */ 3584 for (i = 1; i < ha->rsp_queues_cnt; i++) { 3585 rval = ql_init_rsp_q(ha, ha->rsp_queues[i], 3586 opt); 3587 if (rval != QL_SUCCESS) { 3588 EL(ha, "ql_init_rsp_q=%xh\n", rval); 3589 return (rval); 3590 } 3591 } 3592 } 3593 } 3594 ql_free_dma_resource(ha, &mem_desc); 3595 3596 if (rval != QL_SUCCESS) { 3597 EL(ha, "failed=%xh\n", rval); 3598 } else { 3599 /*EMPTY*/ 3600 QL_PRINT_3(ha, "done\n"); 3601 } 3602 3603 return (rval); 3604 } 3605 3606 /* 3607 * ql_get_firmware_state 3608 * Get adapter firmware state. 3609 * 3610 * Input: 3611 * ha: adapter state pointer. 3612 * mr: pointer for mailbox data. 3613 * 3614 * Returns: 3615 * ql local function return status code. 3616 * 3617 * Context: 3618 * Kernel context. 3619 */ 3620 int 3621 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3622 { 3623 int rval; 3624 mbx_cmd_t mc = {0}; 3625 mbx_cmd_t *mcp = &mc; 3626 3627 QL_PRINT_3(ha, "started\n"); 3628 3629 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 3630 mcp->out_mb = MBX_0; 3631 mcp->in_mb = MBX_0_THRU_6; 3632 mcp->timeout = MAILBOX_TOV; 3633 rval = ql_mailbox_command(ha, mcp); 3634 3635 ha->fw_state[0] = mcp->mb[0]; 3636 ha->fw_state[1] = mcp->mb[1]; 3637 ha->fw_state[2] = mcp->mb[2]; 3638 ha->fw_state[3] = mcp->mb[3]; 3639 ha->fw_state[4] = mcp->mb[4]; 3640 ha->fw_state[5] = mcp->mb[5]; 3641 ha->fw_state[6] = mcp->mb[6]; 3642 3643 /* Return mailbox data. */ 3644 if (mr != NULL) { 3645 mr->mb[1] = mcp->mb[1]; 3646 mr->mb[2] = mcp->mb[2]; 3647 mr->mb[3] = mcp->mb[3]; 3648 mr->mb[4] = mcp->mb[4]; 3649 mr->mb[5] = mcp->mb[5]; 3650 mr->mb[6] = mcp->mb[6]; 3651 } 3652 3653 ha->sfp_stat = mcp->mb[2]; 3654 3655 if (rval != QL_SUCCESS) { 3656 EL(ha, "failed=%xh\n", rval); 3657 } else { 3658 /*EMPTY*/ 3659 QL_PRINT_3(ha, "done\n"); 3660 } 3661 3662 return (rval); 3663 } 3664 3665 /* 3666 * ql_get_adapter_id 3667 * Get adapter ID and topology. 3668 * 3669 * Input: 3670 * ha: adapter state pointer. 3671 * mr: pointer for mailbox data. 3672 * 3673 * Returns: 3674 * ql local function return status code. 3675 * 3676 * Context: 3677 * Kernel context. 3678 */ 3679 int 3680 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3681 { 3682 int i, rval; 3683 mbx_cmd_t mc = {0}; 3684 mbx_cmd_t *mcp = &mc; 3685 3686 QL_PRINT_3(ha, "started\n"); 3687 3688 mcp->mb[0] = MBC_GET_ID; 3689 if (ha->flags & VP_ENABLED) { 3690 mcp->mb[9] = ha->vp_index; 3691 } 3692 mcp->out_mb = MBX_9|MBX_0; 3693 mcp->in_mb = MBX_0_THRU_19; 3694 mcp->timeout = MAILBOX_TOV; 3695 3696 rval = ql_mailbox_command(ha, mcp); 3697 3698 /* Return mailbox data. */ 3699 if (mr != NULL) { 3700 for (i = 0; i < 20; i++) { 3701 mr->mb[i] = mcp->mb[i]; 3702 } 3703 } 3704 3705 if (rval != QL_SUCCESS) { 3706 EL(ha, "failed=%xh\n", rval); 3707 } else { 3708 /*EMPTY*/ 3709 QL_PRINT_3(ha, "done\n"); 3710 } 3711 3712 return (rval); 3713 } 3714 3715 /* 3716 * ql_get_fw_version 3717 * Get firmware version. 3718 * 3719 * Input: 3720 * ha: adapter state pointer. 3721 * mr: pointer for mailbox data. 3722 * 3723 * Returns: 3724 * ql local function return status code. 3725 * 3726 * Context: 3727 * Kernel context. 3728 */ 3729 int 3730 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout) 3731 { 3732 int rval, i; 3733 mbx_cmd_t mc = {0}; 3734 mbx_cmd_t *mcp = &mc; 3735 3736 QL_PRINT_3(ha, "started\n"); 3737 3738 mcp->mb[0] = MBC_ABOUT_FIRMWARE; 3739 mcp->out_mb = MBX_0; 3740 if (CFG_IST(ha, CFG_CTRL_83XX)) { 3741 mcp->in_mb = MBX_0_THRU_17; 3742 } else if (CFG_IST(ha, CFG_CTRL_27XX)) { 3743 mcp->in_mb = MBX_0_THRU_25; 3744 } else { 3745 mcp->in_mb = MBX_0_THRU_13; 3746 } 3747 mcp->timeout = timeout; 3748 rval = ql_mailbox_command(ha, mcp); 3749 3750 /* Return mailbox data. */ 3751 if (mr != NULL) { 3752 for (i = 0; i < ha->reg_off->mbox_cnt && mcp->in_mb; i++) { 3753 if (mcp->in_mb & MBX_0) { 3754 mr->mb[i] = mcp->mb[i]; 3755 } 3756 mcp->in_mb >>= 1; 3757 } 3758 } 3759 3760 if (rval != QL_SUCCESS) { 3761 EL(ha, "failed=%xh\n", rval); 3762 } else { 3763 /*EMPTY*/ 3764 QL_PRINT_3(ha, "done\n"); 3765 } 3766 3767 return (rval); 3768 } 3769 3770 /* 3771 * ql_data_rate 3772 * Issue data rate Mailbox Command. 3773 * 3774 * Input: 3775 * ha: adapter state pointer. 3776 * mr: pointer for mailbox data. 3777 * 3778 * Returns: 3779 * ql local function return status code. 3780 * 3781 * Context: 3782 * Kernel context. 3783 */ 3784 int 3785 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 3786 { 3787 int rval; 3788 mbx_cmd_t mc = {0}; 3789 mbx_cmd_t *mcp = &mc; 3790 3791 QL_PRINT_3(ha, "started\n"); 3792 3793 if (mr != NULL) { 3794 mcp->mb[0] = MBC_DATA_RATE; 3795 mcp->mb[1] = mr->mb[1]; 3796 mcp->mb[2] = mr->mb[2]; 3797 mcp->out_mb = MBX_2|MBX_1|MBX_0; 3798 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3799 mcp->timeout = MAILBOX_TOV; 3800 rval = ql_mailbox_command(ha, mcp); 3801 3802 /* Return mailbox data. */ 3803 mr->mb[1] = mcp->mb[1]; 3804 mr->mb[2] = mcp->mb[2]; 3805 mr->mb[3] = mcp->mb[3]; 3806 } else { 3807 rval = QL_FUNCTION_PARAMETER_ERROR; 3808 } 3809 3810 ha->sfp_stat = mcp->mb[2]; 3811 3812 if (rval != QL_SUCCESS) { 3813 EL(ha, "failed=%xh\n", rval); 3814 } else { 3815 /*EMPTY*/ 3816 QL_PRINT_3(ha, "done\n"); 3817 } 3818 3819 return (rval); 3820 } 3821 3822 /* 3823 * ql_Diag_Loopback 3824 * Issue Reset Link Status mailbox command 3825 * 3826 * Input: 3827 * ha: adapter state pointer. 3828 * bp: buffer pointer. 3829 * size: buffer size. 3830 * opt: command options. 3831 * it_cnt: iteration count. 3832 * mr: pointer for mailbox data. 3833 * 3834 * Returns: 3835 * ql local function return status code. 3836 * 3837 * Context: 3838 * Kernel context. 3839 */ 3840 int 3841 ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, 3842 uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr) 3843 { 3844 int rval; 3845 dma_mem_t mem_desc; 3846 mbx_cmd_t mc = {0}; 3847 mbx_cmd_t *mcp = &mc; 3848 3849 QL_PRINT_3(ha, "started\n"); 3850 3851 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3852 QL_SUCCESS) { 3853 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3854 return (rval); 3855 } 3856 3857 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 3858 mcp->mb[1] = opt; 3859 mcp->mb[2] = ha->fcoe_fcf_idx; 3860 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3861 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3862 mcp->mb[10] = LSW(size); 3863 mcp->mb[11] = MSW(size); 3864 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3865 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3866 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3867 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3868 mcp->mb[18] = LSW(it_cnt); 3869 mcp->mb[19] = MSW(it_cnt); 3870 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3871 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3872 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 3873 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 3874 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 3875 mcp->timeout = it_cnt / 300; 3876 if (mcp->timeout < MAILBOX_TOV) { 3877 mcp->timeout = MAILBOX_TOV; 3878 } 3879 rval = ql_mailbox_command(ha, mcp); 3880 3881 if (rval == QL_SUCCESS) { 3882 ql_get_mbox_dma_data(&mem_desc, bp); 3883 } 3884 3885 ql_free_dma_resource(ha, &mem_desc); 3886 3887 /* Return mailbox data. */ 3888 if (mr != NULL) { 3889 mr->mb[0] = mcp->mb[0]; 3890 mr->mb[1] = mcp->mb[1]; 3891 mr->mb[2] = mcp->mb[2]; 3892 mr->mb[3] = mcp->mb[3]; 3893 mr->mb[18] = mcp->mb[18]; 3894 mr->mb[19] = mcp->mb[19]; 3895 } 3896 3897 if (rval != QL_SUCCESS) { 3898 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]); 3899 } else { 3900 /*EMPTY*/ 3901 QL_PRINT_3(ha, "done\n"); 3902 } 3903 3904 return (rval); 3905 } 3906 3907 /* 3908 * ql_diag_echo 3909 * Issue Diag echo mailbox command. Valid for qla23xx HBA's. 3910 * 3911 * Input: 3912 * ha: adapter state pointer. 3913 * bp: buffer pointer. 3914 * size: buffer size. 3915 * opt: command options. 3916 * mr: pointer to mailbox status. 3917 * 3918 * Returns: 3919 * ql local function return status code. 3920 * 3921 * Context: 3922 * Kernel context. 3923 */ 3924 int 3925 ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt, 3926 ql_mbx_data_t *mr) 3927 { 3928 int rval; 3929 dma_mem_t mem_desc; 3930 mbx_cmd_t mc = {0}; 3931 mbx_cmd_t *mcp = &mc; 3932 3933 QL_PRINT_3(ha, "started\n"); 3934 3935 if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) != 3936 QL_SUCCESS) { 3937 EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval); 3938 return (rval); 3939 } 3940 3941 mcp->mb[0] = MBC_ECHO; 3942 mcp->mb[1] = opt; 3943 mcp->mb[2] = ha->fcoe_fcf_idx; 3944 mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3945 mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3946 mcp->mb[10] = LSW(size); 3947 mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3948 mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3949 mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 3950 mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 3951 mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 3952 mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 3953 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| 3954 MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 3955 mcp->in_mb = MBX_1|MBX_0; 3956 mcp->timeout = MAILBOX_TOV; 3957 rval = ql_mailbox_command(ha, mcp); 3958 3959 if (rval == QL_SUCCESS) { 3960 ql_get_mbox_dma_data(&mem_desc, bp); 3961 } 3962 3963 ql_free_dma_resource(ha, &mem_desc); 3964 3965 if (mr != NULL) { 3966 mr->mb[0] = mcp->mb[0]; 3967 } 3968 3969 if (rval != QL_SUCCESS) { 3970 EL(ha, "failed=%xh, mb1=%xh\n", rval, 3971 mcp->mb[1]); 3972 } else { 3973 /*EMPTY*/ 3974 QL_PRINT_3(ha, "done\n"); 3975 } 3976 3977 return (rval); 3978 } 3979 3980 /* 3981 * ql_diag_beacon 3982 * Enable/Disable beaconing via mailbox command. 3983 * 3984 * Input: 3985 * ha: adapter state pointer. 3986 * mr: pointer to mailbox in/out parameters. 3987 * 3988 * Returns: 3989 * ql local function return status code. 3990 * 3991 * Context: 3992 * Kernel context. 3993 */ 3994 int 3995 ql_diag_beacon(ql_adapter_state_t *ha, int cmd, ql_mbx_data_t *mr) 3996 { 3997 int rval; 3998 mbx_cmd_t mc = {0}; 3999 mbx_cmd_t *mcp = &mc; 4000 4001 mcp->mb[0] = MBC_SET_LED_CONFIG; 4002 if (cmd == QL_BEACON_ENABLE) { 4003 mcp->mb[7] = 0xE; 4004 } else if (cmd == QL_BEACON_DISABLE) { 4005 mcp->mb[7] = 0xD; 4006 } else { 4007 return (EIO); 4008 } 4009 mcp->out_mb = MBX_7|MBX_0; 4010 mcp->in_mb = MBX_0; 4011 mcp->timeout = MAILBOX_TOV; 4012 4013 rval = ql_mailbox_command(ha, mcp); 4014 4015 /* Return mailbox data. */ 4016 if (mr != NULL) { 4017 mr->mb[0] = mcp->mb[0]; 4018 } 4019 4020 if (rval != QL_SUCCESS) { 4021 EL(ha, "failed=%xh\n", rval); 4022 } 4023 4024 return (rval); 4025 } 4026 4027 4028 /* 4029 * ql_serdes_param 4030 * Set/Get serdes transmit parameters mailbox command. 4031 * 4032 * Input: 4033 * ha: adapter state pointer. 4034 * mr: pointer to mailbox in/out parameters. 4035 * 4036 * Returns: 4037 * ql local function return status code. 4038 * 4039 * Context: 4040 * Kernel context. 4041 */ 4042 int 4043 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4044 { 4045 int rval; 4046 mbx_cmd_t mc = {0}; 4047 mbx_cmd_t *mcp = &mc; 4048 4049 QL_PRINT_3(ha, "started\n"); 4050 4051 mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS; 4052 mcp->mb[1] = mr->mb[1]; 4053 mcp->mb[2] = mr->mb[2]; 4054 mcp->mb[3] = mr->mb[3]; 4055 mcp->mb[4] = mr->mb[4]; 4056 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4057 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0; 4058 mcp->timeout = MAILBOX_TOV; 4059 rval = ql_mailbox_command(ha, mcp); 4060 4061 /* Return mailbox data. */ 4062 mr->mb[0] = mcp->mb[0]; 4063 mr->mb[2] = mcp->mb[2]; 4064 mr->mb[3] = mcp->mb[3]; 4065 mr->mb[4] = mcp->mb[4]; 4066 4067 if (rval != QL_SUCCESS) { 4068 EL(ha, "failed=%xh\n", rval); 4069 } else { 4070 /*EMPTY*/ 4071 QL_PRINT_3(ha, "done\n"); 4072 } 4073 4074 return (rval); 4075 } 4076 4077 /* 4078 * ql_get_timeout_parameters 4079 * Issue get timeout parameters mailbox command. 4080 * 4081 * Input: 4082 * ha: adapter state pointer. 4083 * mr: pointer to mailbox in/out parameters. 4084 * 4085 * Returns: 4086 * ql local function return status code. 4087 * 4088 * Context: 4089 * Kernel context. 4090 */ 4091 int 4092 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov) 4093 { 4094 int rval; 4095 mbx_cmd_t mc = {0}; 4096 mbx_cmd_t *mcp = &mc; 4097 4098 QL_PRINT_3(ha, "started\n"); 4099 4100 mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS; 4101 mcp->mb[1] = ha->fcoe_fcf_idx; 4102 mcp->out_mb = MBX_1|MBX_0; 4103 mcp->in_mb = MBX_3|MBX_0; 4104 mcp->timeout = MAILBOX_TOV; 4105 rval = ql_mailbox_command(ha, mcp); 4106 if (rval == QL_SUCCESS) { 4107 /* Get 2 * R_A_TOV in seconds */ 4108 if (CFG_IST(ha, CFG_CTRL_22XX) || mcp->mb[3] == 0) { 4109 *tov = R_A_TOV_DEFAULT; 4110 } else { 4111 *tov = (uint16_t)(mcp->mb[3] / 10); 4112 if (mcp->mb[3] % 10 != 0) { 4113 *tov = (uint16_t)(*tov + 1); 4114 } 4115 /* 4116 * Adjust value to prevent driver timeout at the same 4117 * time as device. 4118 */ 4119 *tov = (uint16_t)(*tov + 5); 4120 } 4121 } else { 4122 *tov = R_A_TOV_DEFAULT; 4123 } 4124 4125 if (rval != QL_SUCCESS) { 4126 EL(ha, "failed=%xh\n", rval); 4127 } else { 4128 /*EMPTY*/ 4129 QL_PRINT_3(ha, "done\n"); 4130 } 4131 4132 return (rval); 4133 } 4134 4135 /* 4136 * ql_stop_firmware 4137 * Issue stop firmware Mailbox Command. 4138 * 4139 * Input: 4140 * ha: adapter state pointer. 4141 * 4142 * Returns: 4143 * ql local function return status code. 4144 * 4145 * Context: 4146 * Kernel context. 4147 */ 4148 int 4149 ql_stop_firmware(ql_adapter_state_t *ha) 4150 { 4151 int rval; 4152 mbx_cmd_t mc = {0}; 4153 mbx_cmd_t *mcp = &mc; 4154 4155 QL_PRINT_3(ha, "started\n"); 4156 4157 mcp->mb[0] = MBC_STOP_FIRMWARE; 4158 mcp->out_mb = MBX_1|MBX_0; 4159 mcp->in_mb = MBX_0; 4160 mcp->timeout = 2; 4161 rval = ql_mailbox_command(ha, mcp); 4162 4163 if (rval != QL_SUCCESS) { 4164 EL(ha, "failed=%xh\n", rval); 4165 } else { 4166 /*EMPTY*/ 4167 QL_PRINT_3(ha, "done\n"); 4168 } 4169 4170 return (rval); 4171 } 4172 4173 /* 4174 * ql_read_sfp 4175 * Issue Read SFP Mailbox command 4176 * 4177 * Input: 4178 * ha: adapter state pointer. 4179 * mem: pointer to dma memory object for command. 4180 * dev: Device address (A0h or A2h). 4181 * addr: Data address on SFP EEPROM (0-255). 4182 * 4183 * Returns: 4184 * ql local function return status code. 4185 * 4186 * Context: 4187 * Kernel context. 4188 */ 4189 int 4190 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev, 4191 uint16_t addr) 4192 { 4193 int rval; 4194 mbx_cmd_t mc = {0}; 4195 mbx_cmd_t *mcp = &mc; 4196 4197 QL_PRINT_3(ha, "started\n"); 4198 4199 mcp->mb[0] = MBC_READ_SFP; 4200 mcp->mb[1] = dev; 4201 mcp->mb[2] = MSW(mem->cookies->dmac_address); 4202 mcp->mb[3] = LSW(mem->cookies->dmac_address); 4203 mcp->mb[6] = MSW(mem->cookies->dmac_notused); 4204 mcp->mb[7] = LSW(mem->cookies->dmac_notused); 4205 mcp->mb[8] = LSW(mem->size); 4206 mcp->mb[9] = addr; 4207 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 4208 mcp->in_mb = MBX_1|MBX_0; 4209 mcp->timeout = MAILBOX_TOV; 4210 rval = ql_mailbox_command(ha, mcp); 4211 4212 (void) ddi_dma_sync(mem->dma_handle, 0, mem->size, 4213 DDI_DMA_SYNC_FORKERNEL); 4214 4215 if (rval != QL_SUCCESS) { 4216 EL(ha, "failed=%xh\n", rval); 4217 } else { 4218 /*EMPTY*/ 4219 QL_PRINT_3(ha, "done\n"); 4220 } 4221 4222 return (rval); 4223 } 4224 4225 /* 4226 * ql_iidma_rate 4227 * Issue get/set iidma rate command 4228 * 4229 * Input: 4230 * ha: adapter state pointer. 4231 * loop_id: n-port handle to set/get iidma rate. 4232 * idma_rate: Pointer to iidma rate. 4233 * option: iidma firmware option (set or get data). 4234 * 0 --> Get iidma rate 4235 * 1 --> Set iidma rate 4236 * 4237 * Returns: 4238 * ql local function return status code. 4239 * 4240 * Context: 4241 * Kernel context. 4242 */ 4243 int 4244 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate, 4245 uint32_t option) 4246 { 4247 int rval; 4248 mbx_cmd_t mc = {0}; 4249 mbx_cmd_t *mcp = &mc; 4250 4251 QL_PRINT_3(ha, "started\n"); 4252 4253 mcp->mb[0] = MBC_PORT_PARAM; 4254 mcp->mb[1] = loop_id; 4255 mcp->mb[2] = (uint16_t)option; 4256 mcp->out_mb = MBX_0|MBX_1|MBX_2; 4257 mcp->in_mb = MBX_0|MBX_1; 4258 4259 if (option & BIT_0) { 4260 mcp->mb[3] = (uint16_t)*idma_rate; 4261 mcp->out_mb |= MBX_3; 4262 } else { 4263 mcp->in_mb |= MBX_3; 4264 } 4265 4266 mcp->timeout = MAILBOX_TOV; 4267 rval = ql_mailbox_command(ha, mcp); 4268 4269 if (rval != QL_SUCCESS) { 4270 EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]); 4271 } else { 4272 if (option == 0) { 4273 *idma_rate = mcp->mb[3]; 4274 } 4275 4276 QL_PRINT_3(ha, "done\n"); 4277 } 4278 4279 return (rval); 4280 } 4281 4282 /* 4283 * ql_set_xmit_parms 4284 * Set transmit parameters 4285 * 4286 * Input: 4287 * ha: adapter state pointer. 4288 * 4289 * Returns: 4290 * ql local function return status code. 4291 * 4292 * Context: 4293 * Kernel context. 4294 */ 4295 int 4296 ql_set_xmit_parms(ql_adapter_state_t *ha) 4297 { 4298 int rval; 4299 mbx_cmd_t mc = {0}; 4300 mbx_cmd_t *mcp = &mc; 4301 4302 QL_PRINT_3(ha, "started\n"); 4303 4304 mcp->mb[0] = MBC_XMIT_PARM; 4305 mcp->mb[1] = BIT_1; 4306 mcp->out_mb = MBX_1|MBX_0; 4307 mcp->in_mb = MBX_0; 4308 mcp->timeout = MAILBOX_TOV; 4309 rval = ql_mailbox_command(ha, mcp); 4310 4311 if (rval != QL_SUCCESS) { 4312 EL(ha, "failed=%xh\n", rval); 4313 } else { 4314 /*EMPTY*/ 4315 QL_PRINT_3(ha, "done\n"); 4316 } 4317 return (rval); 4318 } 4319 4320 /* 4321 * ql_fw_etrace 4322 * Firmware extended tracing. 4323 * 4324 * Input: 4325 * ha: adapter state pointer. 4326 * mem: pointer to dma memory object for command. 4327 * opt: options and opcode. 4328 * mr: pointer to mailbox in/out parameters. 4329 * 4330 * Returns: 4331 * ql local function return status code. 4332 * 4333 * Context: 4334 * Kernel context. 4335 */ 4336 int 4337 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt, 4338 ql_mbx_data_t *mr) 4339 { 4340 int rval = QL_SUCCESS; 4341 mbx_cmd_t mc = {0}; 4342 mbx_cmd_t *mcp = &mc; 4343 uint16_t op_code; 4344 uint64_t time; 4345 4346 QL_PRINT_3(ha, "started\n"); 4347 4348 /* currently no supported options */ 4349 op_code = (uint16_t)(opt & ~0xFF00); 4350 4351 mcp->mb[0] = MBC_TRACE_CONTROL; 4352 mcp->mb[1] = op_code; 4353 mcp->in_mb = MBX_0; 4354 mcp->timeout = MAILBOX_TOV; 4355 4356 switch (op_code) { 4357 case FTO_INSERT_TIME_STAMP: 4358 4359 (void) drv_getparm(TIME, &time); 4360 4361 EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time)); 4362 4363 mcp->mb[2] = LSW(LSD(time)); 4364 mcp->mb[3] = MSW(LSD(time)); 4365 mcp->mb[4] = LSW(MSD(time)); 4366 mcp->mb[5] = MSW(MSD(time)); 4367 mcp->out_mb = MBX_0_THRU_5; 4368 break; 4369 4370 case FTO_FCE_TRACE_ENABLE: 4371 /* Firmware Fibre Channel Event Trace Buffer */ 4372 mcp->mb[2] = LSW(mem->cookies->dmac_address); 4373 mcp->mb[3] = MSW(mem->cookies->dmac_address); 4374 mcp->mb[4] = LSW(mem->cookies->dmac_notused); 4375 mcp->mb[5] = MSW(mem->cookies->dmac_notused); 4376 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */ 4377 mcp->mb[8] = (uint16_t)ha->fwfcetraceopt; 4378 mcp->mb[9] = FTO_FCEMAXTRACEBUF; 4379 mcp->mb[10] = FTO_FCEMAXTRACEBUF; 4380 mcp->out_mb = MBX_0_THRU_10; 4381 break; 4382 4383 case FTO_EXT_TRACE_ENABLE: 4384 /* Firmware Extended Trace Buffer */ 4385 mcp->mb[2] = LSW(mem->cookies->dmac_address); 4386 mcp->mb[3] = MSW(mem->cookies->dmac_address); 4387 mcp->mb[4] = LSW(mem->cookies->dmac_notused); 4388 mcp->mb[5] = MSW(mem->cookies->dmac_notused); 4389 mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */ 4390 mcp->out_mb = MBX_0_THRU_7; 4391 break; 4392 4393 case FTO_FCE_TRACE_DISABLE: 4394 /* also causes ISP25xx to flush its internal FCE buffer. */ 4395 mcp->mb[2] = BIT_0; 4396 mcp->out_mb = MBX_0_THRU_2; 4397 break; 4398 4399 case FTO_EXT_TRACE_DISABLE: 4400 /* just sending the opcode disables it */ 4401 break; 4402 4403 default: 4404 EL(ha, "invalid option: %xh\n", opt); 4405 rval = QL_PARAMETER_ERROR; 4406 break; 4407 } 4408 4409 if (rval == QL_SUCCESS) { 4410 rval = ql_mailbox_command(ha, mcp); 4411 } 4412 4413 /* Return mailbox data. */ 4414 if (mr != NULL) { 4415 mr->mb[0] = mcp->mb[0]; 4416 mr->mb[1] = mcp->mb[1]; 4417 mr->mb[2] = mcp->mb[2]; 4418 mr->mb[3] = mcp->mb[3]; 4419 mr->mb[4] = mcp->mb[4]; 4420 mr->mb[5] = mcp->mb[5]; 4421 mr->mb[6] = mcp->mb[6]; 4422 mr->mb[7] = mcp->mb[7]; 4423 mr->mb[8] = mcp->mb[8]; 4424 mr->mb[9] = mcp->mb[9]; 4425 } 4426 4427 if (rval != QL_SUCCESS) { 4428 EL(ha, "failed=%xh\n", rval); 4429 } else { 4430 /*EMPTY*/ 4431 QL_PRINT_3(ha, "done\n"); 4432 } 4433 4434 return (rval); 4435 } 4436 4437 /* 4438 * ql_reset_menlo 4439 * Reset Menlo Mailbox Command. 4440 * 4441 * Input: 4442 * ha: adapter state pointer. 4443 * mr: pointer to mailbox in/out parameters. 4444 * opt: options. 4445 * 4446 * Returns: 4447 * ql local function return status code. 4448 * 4449 * Context: 4450 * Kernel context. 4451 */ 4452 int 4453 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt) 4454 { 4455 int rval; 4456 mbx_cmd_t mc = {0}; 4457 mbx_cmd_t *mcp = &mc; 4458 4459 QL_PRINT_3(ha, "started\n"); 4460 4461 mcp->mb[0] = MBC_RESET_MENLO; 4462 mcp->mb[1] = opt; 4463 mcp->out_mb = MBX_1|MBX_0; 4464 mcp->in_mb = MBX_1|MBX_0; 4465 mcp->timeout = MAILBOX_TOV; 4466 rval = ql_mailbox_command(ha, mcp); 4467 4468 /* Return mailbox data. */ 4469 if (mr != NULL) { 4470 mr->mb[0] = mcp->mb[0]; 4471 mr->mb[1] = mcp->mb[1]; 4472 } 4473 4474 if (rval != QL_SUCCESS) { 4475 EL(ha, "failed=%xh\n", rval); 4476 } else { 4477 /*EMPTY*/ 4478 QL_PRINT_3(ha, "done\n"); 4479 } 4480 4481 return (rval); 4482 } 4483 4484 /* 4485 * ql_restart_mpi 4486 * The Restart MPI Firmware Mailbox Command will reset the MPI RISC, 4487 * reload MPI firmware from Flash, and execute the firmware. 4488 * 4489 * Input: 4490 * ha: adapter state pointer. 4491 * 4492 * Returns: 4493 * ql local function return status code. 4494 * 4495 * Context: 4496 * Kernel context. 4497 */ 4498 int 4499 ql_restart_mpi(ql_adapter_state_t *ha) 4500 { 4501 int rval; 4502 mbx_cmd_t mc = {0}; 4503 mbx_cmd_t *mcp = &mc; 4504 4505 QL_PRINT_3(ha, "started\n"); 4506 4507 mcp->mb[0] = MBC_RESTART_MPI; 4508 mcp->out_mb = MBX_0; 4509 mcp->in_mb = MBX_1|MBX_0; 4510 mcp->timeout = MAILBOX_TOV; 4511 rval = ql_mailbox_command(ha, mcp); 4512 4513 /* Return mailbox data. */ 4514 if (rval != QL_SUCCESS) { 4515 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 4516 } else { 4517 /*EMPTY*/ 4518 QL_PRINT_3(ha, "done\n"); 4519 } 4520 4521 return (rval); 4522 } 4523 4524 /* 4525 * ql_idc_request 4526 * Inter-Driver Communication Request. 4527 * 4528 * Input: 4529 * ha: adapter state pointer. 4530 * mr: pointer for mailbox data. 4531 * 4532 * Returns: 4533 * ql local function return status code. 4534 * 4535 * Context: 4536 * Kernel context. 4537 */ 4538 int 4539 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 4540 { 4541 int rval; 4542 mbx_cmd_t mc = {0}; 4543 mbx_cmd_t *mcp = &mc; 4544 4545 QL_PRINT_3(ha, "started\n"); 4546 4547 mcp->mb[0] = MBC_IDC_REQUEST; 4548 mcp->mb[1] = mr->mb[1]; 4549 mcp->mb[2] = mr->mb[2]; 4550 mcp->mb[3] = mr->mb[3]; 4551 mcp->mb[4] = mr->mb[4]; 4552 mcp->mb[5] = mr->mb[5]; 4553 mcp->mb[6] = mr->mb[6]; 4554 mcp->mb[7] = mr->mb[7]; 4555 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4556 mcp->in_mb = MBX_2|MBX_0; 4557 mcp->timeout = MAILBOX_TOV; 4558 rval = ql_mailbox_command(ha, mcp); 4559 4560 if (rval == QL_SUCCESS) { 4561 mr->mb[2] = mcp->mb[2]; 4562 QL_PRINT_3(ha, "done\n"); 4563 } else { 4564 EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]); 4565 } 4566 4567 return (rval); 4568 } 4569 4570 /* 4571 * ql_idc_ack 4572 * Inter-Driver Communication Acknowledgement. 4573 * 4574 * Input: 4575 * ha: adapter state pointer. 4576 * 4577 * Returns: 4578 * ql local function return status code. 4579 * 4580 * Context: 4581 * Kernel context. 4582 */ 4583 int 4584 ql_idc_ack(ql_adapter_state_t *ha) 4585 { 4586 int rval; 4587 mbx_cmd_t mc = {0}; 4588 mbx_cmd_t *mcp = &mc; 4589 4590 QL_PRINT_3(ha, "started\n"); 4591 4592 mcp->mb[0] = MBC_IDC_ACK; 4593 mcp->mb[1] = ha->idc_mb[1]; 4594 mcp->mb[2] = ha->idc_mb[2]; 4595 mcp->mb[3] = ha->idc_mb[3]; 4596 mcp->mb[4] = ha->idc_mb[4]; 4597 mcp->mb[5] = ha->idc_mb[5]; 4598 mcp->mb[6] = ha->idc_mb[6]; 4599 mcp->mb[7] = ha->idc_mb[7]; 4600 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4601 mcp->in_mb = MBX_0; 4602 mcp->timeout = MAILBOX_TOV; 4603 rval = ql_mailbox_command(ha, mcp); 4604 4605 QL_PRINT_3(ha, "done\n"); 4606 4607 return (rval); 4608 } 4609 4610 /* 4611 * ql_idc_time_extend 4612 * Inter-Driver Communication Time Extend 4613 * 4614 * Input: 4615 * ha: adapter state pointer. 4616 * 4617 * Returns: 4618 * ql local function return status code. 4619 * 4620 * Context: 4621 * Kernel context. 4622 */ 4623 int 4624 ql_idc_time_extend(ql_adapter_state_t *ha) 4625 { 4626 int rval; 4627 mbx_cmd_t mc = {0}; 4628 mbx_cmd_t *mcp = &mc; 4629 4630 QL_PRINT_3(ha, "started\n"); 4631 4632 mcp->mb[0] = MBC_IDC_TIME_EXTEND; 4633 mcp->mb[1] = ha->idc_mb[1]; 4634 mcp->mb[2] = ha->idc_mb[2]; 4635 mcp->mb[3] = ha->idc_mb[3]; 4636 mcp->mb[4] = ha->idc_mb[4]; 4637 mcp->mb[5] = ha->idc_mb[5]; 4638 mcp->mb[6] = ha->idc_mb[6]; 4639 mcp->mb[7] = ha->idc_mb[7]; 4640 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4641 mcp->in_mb = MBX_0; 4642 mcp->timeout = MAILBOX_TOV; 4643 rval = ql_mailbox_command(ha, mcp); 4644 4645 QL_PRINT_3(ha, "done\n"); 4646 4647 return (rval); 4648 } 4649 4650 /* 4651 * ql_port_reset 4652 * The Port Reset for the external 10G port associated with this function. 4653 * 4654 * Input: 4655 * ha: adapter state pointer. 4656 * 4657 * Returns: 4658 * ql local function return status code. 4659 * 4660 * Context: 4661 * Kernel context. 4662 */ 4663 int 4664 ql_port_reset(ql_adapter_state_t *ha) 4665 { 4666 int rval; 4667 mbx_cmd_t mc = {0}; 4668 mbx_cmd_t *mcp = &mc; 4669 4670 QL_PRINT_3(ha, "started\n"); 4671 4672 mcp->mb[0] = MBC_PORT_RESET; 4673 mcp->out_mb = MBX_0; 4674 mcp->in_mb = MBX_0; 4675 mcp->timeout = MAILBOX_TOV; 4676 rval = ql_mailbox_command(ha, mcp); 4677 4678 QL_PRINT_3(ha, "done\n"); 4679 4680 return (rval); 4681 } 4682 4683 /* 4684 * ql_set_port_config 4685 * The Set Port Configuration command sets the configuration for the 4686 * external 10G port associated with this function. 4687 * 4688 * Input: 4689 * ha: adapter state pointer. 4690 * mr: pointer for mailbox data. 4691 * 4692 * Returns: 4693 * ql local function return status code. 4694 * 4695 * Context: 4696 * Kernel context. 4697 */ 4698 int 4699 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp) 4700 { 4701 int rval; 4702 mbx_cmd_t mc = {0}; 4703 mbx_cmd_t *mcp = &mc; 4704 4705 QL_PRINT_3(ha, "started\n"); 4706 4707 mcp->mb[0] = MBC_SET_PORT_CONFIG; 4708 mcp->mb[1] = mrp->mb[1]; 4709 mcp->mb[2] = mrp->mb[2]; 4710 mcp->mb[3] = mrp->mb[3]; 4711 mcp->mb[4] = mrp->mb[4]; 4712 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4713 mcp->in_mb = MBX_0; 4714 mcp->timeout = MAILBOX_TOV; 4715 rval = ql_mailbox_command(ha, mcp); 4716 4717 QL_PRINT_3(ha, "done\n"); 4718 4719 return (rval); 4720 } 4721 4722 /* 4723 * ql_get_port_config 4724 * The Get Port Configuration command retrieves the current configuration 4725 * for the external 10G port associated with this function. 4726 * 4727 * Input: 4728 * ha: adapter state pointer. 4729 * mr: pointer for mailbox data. 4730 * 4731 * Returns: 4732 * ql local function return status code. 4733 * 4734 * Context: 4735 * Kernel context. 4736 */ 4737 int 4738 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp) 4739 { 4740 int rval; 4741 mbx_cmd_t mc = {0}; 4742 mbx_cmd_t *mcp = &mc; 4743 4744 QL_PRINT_3(ha, "started\n"); 4745 4746 mcp->mb[0] = MBC_GET_PORT_CONFIG; 4747 mcp->out_mb = MBX_0; 4748 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4749 mcp->timeout = MAILBOX_TOV; 4750 rval = ql_mailbox_command(ha, mcp); 4751 4752 if (rval == QL_SUCCESS) { 4753 if (mrp != NULL) { 4754 mrp->mb[1] = mcp->mb[1]; 4755 mrp->mb[2] = mcp->mb[2]; 4756 mrp->mb[3] = mcp->mb[3]; 4757 mrp->mb[4] = mcp->mb[4]; 4758 } 4759 QL_PRINT_3(ha, "done\n"); 4760 } else { 4761 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n", 4762 rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]); 4763 } 4764 4765 return (rval); 4766 } 4767 4768 /* 4769 * ql_flash_access 4770 * The Get Port Configuration command retrieves the current configuration 4771 * for the external 10G port associated with this function 4772 * 4773 * Input: 4774 * ha: adapter state pointer. 4775 * cmd: command. 4776 * start: 32bit word address. 4777 * end: 32bit word address. 4778 * dp: 32bit word pointer. 4779 * 4780 * Returns: 4781 * ql local function return status code. 4782 * 4783 * Context: 4784 * Kernel context. 4785 */ 4786 int 4787 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start, 4788 uint32_t end, uint32_t *dp) 4789 { 4790 int rval; 4791 mbx_cmd_t mc = {0}; 4792 mbx_cmd_t *mcp = &mc; 4793 4794 QL_PRINT_3(ha, "started, cmd=%xh\n", cmd); 4795 4796 mcp->mb[0] = MBC_FLASH_ACCESS; 4797 mcp->mb[1] = cmd; 4798 mcp->mb[2] = LSW(start); 4799 mcp->mb[3] = MSW(start); 4800 mcp->mb[4] = LSW(end); 4801 mcp->mb[5] = MSW(end); 4802 4803 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4804 mcp->in_mb = MBX_0_THRU_4; 4805 mcp->timeout = MAILBOX_TOV; 4806 rval = ql_mailbox_command(ha, mcp); 4807 4808 if (rval != QL_SUCCESS) { 4809 EL(ha, "cmd=%xh, status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, " 4810 "mbx4=%xh\n", cmd, rval, mcp->mb[1], mcp->mb[2], 4811 mcp->mb[3], mcp->mb[4]); 4812 } else { 4813 if (dp != NULL) { 4814 *dp = (uint32_t)mcp->mb[1]; 4815 } 4816 QL_PRINT_3(ha, "done\n"); 4817 } 4818 4819 return (rval); 4820 } 4821 4822 /* 4823 * ql_get_xgmac_stats 4824 * Issue et XGMAC Statistics Mailbox command 4825 * 4826 * Input: 4827 * ha: adapter state pointer. 4828 * size: size of data buffer. 4829 * bufp: data pointer for DMA data. 4830 * 4831 * Returns: 4832 * ql local function return status code. 4833 * 4834 * Context: 4835 * Kernel context. 4836 */ 4837 int 4838 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp) 4839 { 4840 int rval; 4841 dma_mem_t mem_desc; 4842 mbx_cmd_t mc = {0}; 4843 mbx_cmd_t *mcp = &mc; 4844 4845 QL_PRINT_3(ha, "started\n"); 4846 4847 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 4848 (uint32_t)size)) != QL_SUCCESS) { 4849 EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval); 4850 return (QL_MEMORY_ALLOC_FAILED); 4851 } 4852 4853 mcp->mb[0] = MBC_GET_XGMAC_STATS; 4854 mcp->mb[2] = MSW(mem_desc.cookie.dmac_address); 4855 mcp->mb[3] = LSW(mem_desc.cookie.dmac_address); 4856 mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused); 4857 mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused); 4858 mcp->mb[8] = (uint16_t)(size >> 2); 4859 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 4860 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4861 mcp->timeout = MAILBOX_TOV; 4862 rval = ql_mailbox_command(ha, mcp); 4863 4864 if (rval == QL_SUCCESS) { 4865 ql_get_mbox_dma_data(&mem_desc, bufp); 4866 } 4867 ql_free_dma_resource(ha, &mem_desc); 4868 4869 if (rval != QL_SUCCESS) { 4870 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1], 4871 mcp->mb[2]); 4872 } else { 4873 /*EMPTY*/ 4874 QL_PRINT_3(ha, "done\n"); 4875 } 4876 4877 return (rval); 4878 } 4879 4880 /* 4881 * ql_get_dcbx_params 4882 * Issue get DCBX parameters mailbox command. 4883 * 4884 * Input: 4885 * ha: adapter state pointer. 4886 * size: size of data buffer. 4887 * bufp: data pointer for DMA data. 4888 * 4889 * Returns: 4890 * ql local function return status code. 4891 * 4892 * Context: 4893 * Kernel context. 4894 */ 4895 int 4896 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp) 4897 { 4898 int rval; 4899 dma_mem_t mem_desc; 4900 mbx_cmd_t mc = {0}; 4901 mbx_cmd_t *mcp = &mc; 4902 4903 QL_PRINT_3(ha, "started\n"); 4904 4905 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) != 4906 QL_SUCCESS) { 4907 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED); 4908 return (QL_MEMORY_ALLOC_FAILED); 4909 } 4910 4911 mcp->mb[0] = MBC_GET_DCBX_PARAMS; 4912 mcp->mb[1] = 0; /* Return all DCBX paramters */ 4913 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 4914 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 4915 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 4916 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 4917 mcp->mb[8] = (uint16_t)size; 4918 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 4919 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4920 mcp->timeout = MAILBOX_TOV; 4921 rval = ql_mailbox_command(ha, mcp); 4922 4923 if (rval == QL_SUCCESS) { 4924 ql_get_mbox_dma_data(&mem_desc, bufp); 4925 } 4926 4927 ql_free_dma_resource(ha, &mem_desc); 4928 4929 if (rval != QL_SUCCESS) { 4930 EL(ha, "failed=%xh\n", rval); 4931 } else { 4932 /*EMPTY*/ 4933 QL_PRINT_3(ha, "done\n"); 4934 } 4935 4936 return (rval); 4937 } 4938 /* 4939 * ql_get_fcf_list 4940 * Issue get FCF list mailbox command. 4941 * 4942 * Input: 4943 * ha: adapter state pointer. 4944 * fcf_list: pointer to ql_fcf_list_desc_t 4945 * bufp: data pointer for DMA data. 4946 * 4947 * Returns: 4948 * ql local function return status code. 4949 * 4950 * Context: 4951 * Kernel context. 4952 */ 4953 4954 int 4955 ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list, 4956 caddr_t bufp) 4957 { 4958 int rval; 4959 dma_mem_t mem_desc; 4960 mbx_cmd_t mc = {0}; 4961 mbx_cmd_t *mcp = &mc; 4962 4963 QL_PRINT_3(ha, "started\n"); 4964 4965 if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, 4966 fcf_list->buffer_size)) != 4967 QL_SUCCESS) { 4968 EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED); 4969 return (QL_MEMORY_ALLOC_FAILED); 4970 } 4971 4972 mcp->mb[0] = MBC_GET_FCF_LIST; 4973 mcp->mb[1] = fcf_list->options; 4974 mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress)); 4975 mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress)); 4976 mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress)); 4977 mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress)); 4978 mcp->mb[8] = (uint16_t)fcf_list->buffer_size; 4979 mcp->mb[9] = fcf_list->fcf_index; 4980 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 4981 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4982 mcp->timeout = MAILBOX_TOV; 4983 rval = ql_mailbox_command(ha, mcp); 4984 4985 if (rval == QL_SUCCESS) { 4986 ql_get_mbox_dma_data(&mem_desc, bufp); 4987 fcf_list->buffer_size = (uint16_t)mcp->mb[1]; 4988 } 4989 4990 ql_free_dma_resource(ha, &mem_desc); 4991 4992 if (rval != QL_SUCCESS) { 4993 EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1], 4994 mcp->mb[2]); 4995 } else { 4996 /*EMPTY*/ 4997 QL_PRINT_3(ha, "done\n"); 4998 } 4999 5000 return (rval); 5001 } 5002 5003 /* 5004 * ql_get_resource_cnts 5005 * Issue get Resourse Count mailbox command. 5006 * 5007 * Input: 5008 * ha: adapter state pointer. 5009 * mr: pointer for mailbox data. 5010 * 5011 * Returns: 5012 * ql local function return status code. 5013 * 5014 * Context: 5015 * Kernel context. 5016 */ 5017 5018 int 5019 ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5020 { 5021 int rval; 5022 mbx_cmd_t mc = {0}; 5023 mbx_cmd_t *mcp = &mc; 5024 5025 QL_PRINT_3(ha, "started\n"); 5026 5027 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; 5028 mcp->out_mb = MBX_9|MBX_1|MBX_0; 5029 mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6| 5030 MBX_3|MBX_2|MBX_1|MBX_0; 5031 mcp->timeout = MAILBOX_TOV; 5032 rval = ql_mailbox_command(ha, mcp); 5033 5034 /* Return mailbox data. */ 5035 if (mr != NULL) { 5036 mr->mb[1] = mcp->mb[1]; 5037 mr->mb[2] = mcp->mb[2]; 5038 mr->mb[3] = mcp->mb[3]; 5039 mr->mb[6] = mcp->mb[6]; 5040 mr->mb[7] = mcp->mb[7]; 5041 mr->mb[10] = mcp->mb[10]; 5042 mr->mb[11] = mcp->mb[11]; 5043 mr->mb[12] = mcp->mb[12]; 5044 } 5045 5046 if (rval != QL_SUCCESS) { 5047 EL(ha, "failed=%xh\n", rval); 5048 } else { 5049 /*EMPTY*/ 5050 QL_PRINT_3(ha, "done\n"); 5051 } 5052 5053 return (rval); 5054 } 5055 5056 /* 5057 * ql_toggle_interrupt 5058 * Issue Toggle Interrupt Mailbox Command. 5059 * 5060 * Input: 5061 * ha: adapter state pointer. 5062 * opt: 0 = disable, 1 = enable. 5063 * 5064 * Returns: 5065 * ql local function return status code. 5066 * 5067 * Context: 5068 * Kernel context. 5069 */ 5070 int 5071 ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt) 5072 { 5073 int rval; 5074 mbx_cmd_t mc = {0}; 5075 mbx_cmd_t *mcp = &mc; 5076 5077 QL_PRINT_3(ha, "started\n"); 5078 5079 mcp->mb[0] = MBC_TOGGLE_INTERRUPT; 5080 mcp->mb[1] = opt; 5081 mcp->out_mb = MBX_1|MBX_0; 5082 mcp->in_mb = MBX_0; 5083 mcp->timeout = 2; 5084 rval = ql_mailbox_command(ha, mcp); 5085 5086 if (rval != QL_SUCCESS) { 5087 EL(ha, "failed=%xh\n", rval); 5088 } else { 5089 /*EMPTY*/ 5090 QL_PRINT_3(ha, "done\n"); 5091 } 5092 5093 return (rval); 5094 } 5095 5096 /* 5097 * ql_get_md_template 5098 * Issue request mini-dump template Mailbox command 5099 * 5100 * Input: 5101 * ha: adapter state pointer. 5102 * mem: pointer to dma memory object for command. 5103 * mr: pointer for return mailboxes. 5104 * ofst: template offset. 5105 * opt: request command code. 5106 * GTO_TEMPLATE_SIZE = Request Template Size. 5107 * GTO_TEMPLATE = Request Template. 5108 * 5109 * Returns: 5110 * ql local function return status code. 5111 * 5112 * Context: 5113 * Kernel context. 5114 */ 5115 int 5116 ql_get_md_template(ql_adapter_state_t *ha, dma_mem_t *mem, ql_mbx_data_t *mr, 5117 uint32_t ofst, uint16_t opt) 5118 { 5119 int rval; 5120 mbx_cmd_t mc = {0}; 5121 mbx_cmd_t *mcp = &mc; 5122 5123 QL_PRINT_3(ha, "started\n"); 5124 5125 mcp->mb[0] = MBC_GET_MD_TEMPLATE; 5126 mcp->mb[2] = opt; 5127 if (mem != NULL) { 5128 mcp->mb[4] = LSW(mem->cookies->dmac_address); 5129 mcp->mb[5] = MSW(mem->cookies->dmac_address); 5130 mcp->mb[6] = LSW(mem->cookies->dmac_notused); 5131 mcp->mb[7] = MSW(mem->cookies->dmac_notused); 5132 mcp->mb[8] = LSW(mem->size); 5133 mcp->mb[9] = MSW(mem->size); 5134 } 5135 if (ofst != 0) { 5136 mcp->mb[10] = LSW(ofst); 5137 mcp->mb[11] = MSW(ofst); 5138 } 5139 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3| 5140 MBX_2|MBX_1|MBX_0; 5141 mcp->in_mb = MBX_15|MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8| 5142 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5143 mcp->timeout = MAILBOX_TOV; 5144 rval = ql_mailbox_command(ha, mcp); 5145 5146 /* Return mailbox data. */ 5147 if (mr != NULL) { 5148 mr->mb[0] = mcp->mb[0]; 5149 mr->mb[1] = mcp->mb[1]; 5150 mr->mb[2] = mcp->mb[2]; 5151 mr->mb[3] = mcp->mb[3]; 5152 mr->mb[4] = mcp->mb[4]; 5153 mr->mb[5] = mcp->mb[5]; 5154 mr->mb[6] = mcp->mb[6]; 5155 mr->mb[7] = mcp->mb[7]; 5156 mr->mb[8] = mcp->mb[8]; 5157 mr->mb[9] = mcp->mb[9]; 5158 mr->mb[10] = mcp->mb[10]; 5159 mr->mb[11] = mcp->mb[11]; 5160 mr->mb[12] = mcp->mb[12]; 5161 mr->mb[13] = mcp->mb[13]; 5162 mr->mb[12] = mcp->mb[14]; 5163 mr->mb[13] = mcp->mb[15]; 5164 } 5165 5166 if (rval != QL_SUCCESS) { 5167 EL(ha, "failed=%xh\n", rval); 5168 } else { 5169 /*EMPTY*/ 5170 QL_PRINT_3(ha, "done\n"); 5171 } 5172 return (rval); 5173 } 5174 5175 /* 5176 * ql_init_req_q 5177 * Initialize request queue. 5178 * 5179 * Input: 5180 * ha: adapter state pointer. 5181 * req_q: request queue structure pointer. 5182 * opt: Initialize Multiple Queue mailbox command options. 5183 * 5184 * Returns: 5185 * ql driver local function return status codes 5186 * 5187 * Context: 5188 * Kernel context. 5189 */ 5190 static int 5191 ql_init_req_q(ql_adapter_state_t *ha, ql_request_q_t *req_q, uint16_t opt) 5192 { 5193 int rval; 5194 mbx_cmd_t mc = {0}; 5195 mbx_cmd_t *mcp = &mc; 5196 5197 QL_PRINT_3(ha, "started, req_q_number=%d\n", req_q->req_q_number); 5198 5199 if (!(opt & IMO_QOS_UPDATE)) { 5200 req_q->req_ring_ptr = req_q->req_ring.bp; 5201 req_q->req_ring_index = 0; 5202 req_q->req_q_cnt = (uint16_t)(req_q->req_entry_cnt - 1); 5203 WR32_MBAR_REG(ha, req_q->mbar_req_in, 0); 5204 if (req_q->req_out_shadow_ptr) { 5205 *req_q->req_out_shadow_ptr = 0; 5206 } 5207 } 5208 5209 mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE; 5210 mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED); 5211 mcp->mb[2] = MSW(LSD(req_q->req_ring.cookie.dmac_laddress)); 5212 mcp->mb[3] = LSW(LSD(req_q->req_ring.cookie.dmac_laddress)); 5213 mcp->mb[4] = req_q->req_q_number; 5214 mcp->mb[5] = req_q->req_entry_cnt; 5215 mcp->mb[6] = MSW(MSD(req_q->req_ring.cookie.dmac_laddress)); 5216 mcp->mb[7] = LSW(MSD(req_q->req_ring.cookie.dmac_laddress)); 5217 mcp->mb[11] = ha->vp_index; 5218 mcp->mb[12] = 0; 5219 mcp->mb[14] = 1; 5220 mcp->out_mb = MBX_0_THRU_14; 5221 mcp->in_mb = MBX_0_THRU_1; 5222 mcp->timeout = MAILBOX_TOV; 5223 rval = ql_mailbox_command(ha, mcp); 5224 5225 if (rval != QL_SUCCESS) { 5226 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 5227 } else { 5228 /*EMPTY*/ 5229 QL_PRINT_3(ha, "done\n"); 5230 } 5231 return (rval); 5232 } 5233 5234 /* 5235 * ql_init_rsp_q 5236 * Initialize response queue. 5237 * 5238 * Input: 5239 * ha: adapter state pointer. 5240 * rsp_q: response queue structure pointer. 5241 * opt: Initialize Multiple Queue mailbox command options. 5242 * 5243 * Returns: 5244 * ql driver local function return status codes 5245 * 5246 * Context: 5247 * Kernel context. 5248 */ 5249 static int 5250 ql_init_rsp_q(ql_adapter_state_t *ha, ql_response_q_t *rsp_q, uint16_t opt) 5251 { 5252 int rval; 5253 mbx_cmd_t mc = {0}; 5254 mbx_cmd_t *mcp = &mc; 5255 5256 QL_PRINT_3(ha, "started, rsp_q_number=%d\n", rsp_q->rsp_q_number); 5257 5258 if (!(opt & IMO_DELETE_Q)) { 5259 rsp_q->rsp_ring_ptr = rsp_q->rsp_ring.bp; 5260 rsp_q->rsp_ring_index = 0; 5261 WR32_MBAR_REG(ha, rsp_q->mbar_rsp_out, 0); 5262 if (rsp_q->rsp_in_shadow_ptr) { 5263 *rsp_q->rsp_in_shadow_ptr = 0; 5264 } 5265 } 5266 5267 mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE; 5268 mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED | 5269 IMO_RESPONSE_Q_SERVICE); 5270 mcp->mb[2] = MSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress)); 5271 mcp->mb[3] = LSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress)); 5272 mcp->mb[4] = rsp_q->rsp_q_number; 5273 mcp->mb[5] = rsp_q->rsp_entry_cnt; 5274 mcp->mb[6] = MSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress)); 5275 mcp->mb[7] = LSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress)); 5276 mcp->mb[14] = rsp_q->msi_x_vector; 5277 mcp->out_mb = MBX_0_THRU_14; 5278 mcp->in_mb = MBX_0_THRU_1; 5279 mcp->timeout = MAILBOX_TOV; 5280 rval = ql_mailbox_command(ha, mcp); 5281 5282 if (rval != QL_SUCCESS) { 5283 EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 5284 } else { 5285 /*EMPTY*/ 5286 QL_PRINT_3(ha, "done\n"); 5287 } 5288 return (rval); 5289 } 5290 5291 /* 5292 * ql_load_flash_image 5293 * Load Flash Firmware. 5294 * 5295 * Input: 5296 * ha: adapter state pointer. 5297 * 5298 * Returns: 5299 * ql local function return status code. 5300 * 5301 * Context: 5302 * Kernel context. 5303 */ 5304 int 5305 ql_load_flash_image(ql_adapter_state_t *ha) 5306 { 5307 int rval; 5308 mbx_cmd_t mc = {0}; 5309 mbx_cmd_t *mcp = &mc; 5310 5311 QL_PRINT_3(ha, "started\n"); 5312 5313 mcp->mb[0] = MBC_LOAD_FLASH_IMAGE; 5314 mcp->out_mb = MBX_0; 5315 mcp->in_mb = MBX_2|MBX_1|MBX_0; 5316 mcp->timeout = MAILBOX_TOV; 5317 rval = ql_mailbox_command(ha, mcp); 5318 5319 if (rval != QL_SUCCESS) { 5320 EL(ha, "failed, rval=%xh, mbx1=%xh, mbx2=%xh\n", 5321 rval, mcp->mb[1], mcp->mb[2]); 5322 } else { 5323 /*EMPTY*/ 5324 QL_PRINT_3(ha, "done\n"); 5325 } 5326 return (rval); 5327 } 5328 5329 /* 5330 * ql_set_led_config 5331 * Set LED Configuration. 5332 * 5333 * Input: 5334 * ha: adapter state pointer. 5335 * mr: pointer for mailbox data. 5336 * 5337 * Returns: 5338 * ql local function return status code. 5339 * 5340 * Context: 5341 * Kernel context. 5342 */ 5343 int 5344 ql_set_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5345 { 5346 int rval; 5347 mbx_cmd_t mc = {0}; 5348 mbx_cmd_t *mcp = &mc; 5349 5350 QL_PRINT_3(ha, "started\n"); 5351 5352 mcp->mb[0] = MBC_SET_LED_CONFIG; 5353 mcp->mb[1] = mr->mb[1]; 5354 mcp->mb[2] = mr->mb[2]; 5355 mcp->mb[3] = mr->mb[3]; 5356 mcp->mb[4] = mr->mb[4]; 5357 mcp->mb[5] = mr->mb[5]; 5358 mcp->mb[6] = mr->mb[6]; 5359 mcp->out_mb = MBX_0_THRU_6; 5360 mcp->in_mb = MBX_0; 5361 mcp->timeout = MAILBOX_TOV; 5362 rval = ql_mailbox_command(ha, mcp); 5363 5364 if (rval != QL_SUCCESS) { 5365 EL(ha, "failed=%xh\n", rval); 5366 } else { 5367 /*EMPTY*/ 5368 QL_PRINT_3(ha, "done\n"); 5369 } 5370 5371 return (rval); 5372 } 5373 /* 5374 * ql_get_led_config 5375 * Get LED Configuration. 5376 * 5377 * Input: 5378 * ha: adapter state pointer. 5379 * mr: pointer for mailbox data. 5380 * 5381 * Returns: 5382 * ql local function return status code. 5383 * 5384 * Context: 5385 * Kernel context. 5386 */ 5387 int 5388 ql_get_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5389 { 5390 int rval; 5391 mbx_cmd_t mc = {0}; 5392 mbx_cmd_t *mcp = &mc; 5393 5394 QL_PRINT_3(ha, "started\n"); 5395 5396 mcp->mb[0] = MBC_GET_LED_CONFIG; 5397 mcp->out_mb = MBX_0; 5398 mcp->in_mb = MBX_0_THRU_6; 5399 mcp->timeout = MAILBOX_TOV; 5400 rval = ql_mailbox_command(ha, mcp); 5401 5402 /* Return config data. */ 5403 if (mr != NULL) { 5404 mr->mb[1] = mcp->mb[1]; 5405 mr->mb[2] = mcp->mb[2]; 5406 mr->mb[3] = mcp->mb[3]; 5407 mr->mb[4] = mcp->mb[4]; 5408 mr->mb[5] = mcp->mb[5]; 5409 mr->mb[6] = mcp->mb[6]; 5410 } 5411 5412 if (rval != QL_SUCCESS) { 5413 EL(ha, "failed=%xh\n", rval); 5414 } else { 5415 /*EMPTY*/ 5416 QL_PRINT_3(ha, "done\n"); 5417 } 5418 5419 return (rval); 5420 } 5421 5422 /* 5423 * ql_led_config 5424 * Set/Get Fibre Channel LED Configuration command. 5425 * 5426 * Input: 5427 * ha: adapter state pointer. 5428 * opt: Options. 5429 * led0: LED 0 configuration. 5430 * led1: LED 1 configuration. 5431 * led2: LED 2 configuration. 5432 * mr: pointer for mailbox data. 5433 * 5434 * Returns: 5435 * qlc local function return status code. 5436 * 5437 * Context: 5438 * Kernel context. 5439 */ 5440 int 5441 ql_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5442 { 5443 int rval = QL_SUCCESS; 5444 mbx_cmd_t mc = {0}; 5445 mbx_cmd_t *mcp = &mc; 5446 5447 QL_PRINT_3(ha, "started\n"); 5448 5449 mcp->mb[0] = MBC_FC_LED_CONFIG; 5450 mcp->mb[1] = mr->mb[1]; 5451 mcp->mb[2] = mr->mb[2]; 5452 mcp->mb[3] = mr->mb[3]; 5453 mcp->mb[4] = mr->mb[4]; 5454 mcp->out_mb = MBX_0_THRU_4; 5455 mcp->in_mb = MBX_0_THRU_4; 5456 mcp->timeout = MAILBOX_TOV; 5457 rval = ql_mailbox_command(ha, mcp); 5458 5459 /* Return mailbox data. */ 5460 mr->mb[0] = mcp->mb[0]; 5461 mr->mb[1] = mcp->mb[1]; 5462 mr->mb[2] = mcp->mb[2]; 5463 mr->mb[3] = mcp->mb[3]; 5464 mr->mb[4] = mcp->mb[4]; 5465 5466 if (rval != QL_SUCCESS) { 5467 EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 5468 } else { 5469 /*EMPTY*/ 5470 QL_PRINT_3(ha, "done\n"); 5471 } 5472 return (rval); 5473 } 5474 5475 /* 5476 * ql_write_remote_reg 5477 * Writes a register within another function. 5478 * 5479 * Input: 5480 * ha: adapter state pointer. 5481 * addr: address. 5482 * data: data. 5483 * 5484 * Returns: 5485 * ql local function return status code. 5486 * 5487 * Context: 5488 * Kernel context. 5489 */ 5490 int 5491 ql_write_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t data) 5492 { 5493 int rval; 5494 mbx_cmd_t mc = {0}; 5495 mbx_cmd_t *mcp = &mc; 5496 5497 QL_PRINT_10(ha, "started, addr=%xh, data=%xh\n", addr, data); 5498 5499 mcp->mb[0] = MBC_WRITE_REMOTE_REG; 5500 mcp->mb[1] = LSW(addr); 5501 mcp->mb[2] = MSW(addr); 5502 mcp->mb[3] = LSW(data); 5503 mcp->mb[4] = MSW(data); 5504 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5505 mcp->in_mb = MBX_1|MBX_0; 5506 mcp->timeout = MAILBOX_TOV; 5507 rval = ql_mailbox_command(ha, mcp); 5508 5509 if (rval != QL_SUCCESS) { 5510 EL(ha, "failed=%xh, mbx1=%xh, addr=%xh, data=%xh\n", rval, 5511 mcp->mb[1], addr, data); 5512 } else { 5513 /*EMPTY*/ 5514 QL_PRINT_10(ha, "done\n"); 5515 } 5516 return (rval); 5517 } 5518 5519 /* 5520 * ql_read_remote_reg 5521 * Read a register within another function. 5522 * 5523 * Input: 5524 * ha: adapter state pointer. 5525 * addr: address. 5526 * data: data pointer. 5527 * 5528 * Returns: 5529 * qlc local function return status code. 5530 * 5531 * Context: 5532 * Kernel context. 5533 */ 5534 int 5535 ql_read_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t *dp) 5536 { 5537 int rval; 5538 mbx_cmd_t mc = {0}; 5539 mbx_cmd_t *mcp = &mc; 5540 5541 QL_PRINT_10(ha, "started, addr=%xh\n", addr); 5542 5543 mcp->mb[0] = MBC_READ_REMOTE_REG; 5544 mcp->mb[1] = LSW(addr); 5545 mcp->mb[2] = MSW(addr); 5546 mcp->out_mb = MBX_2|MBX_1|MBX_0; 5547 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0; 5548 mcp->timeout = MAILBOX_TOV; 5549 rval = ql_mailbox_command(ha, mcp); 5550 5551 if (rval != QL_SUCCESS) { 5552 EL(ha, "failed=%xh, mbx1=%xh, addr=%xh\n", rval, mcp->mb[1], 5553 addr); 5554 } else { 5555 *dp = SHORT_TO_LONG(mcp->mb[3], mcp->mb[4]); 5556 QL_PRINT_10(ha, "done, addr=%xh, data=%xh\n", addr, *dp); 5557 } 5558 return (rval); 5559 } 5560 5561 /* 5562 * ql_get_temp 5563 * Issue get temperature mailbox command. 5564 * 5565 * Input: 5566 * ha: adapter state pointer. 5567 * mr: pointer for mailbox data. 5568 * 5569 * Returns: 5570 * ql local function return status code. 5571 * 5572 * Context: 5573 * Kernel context. 5574 */ 5575 int 5576 ql_get_temp(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5577 { 5578 int rval; 5579 mbx_cmd_t mc = {0}; 5580 mbx_cmd_t *mcp = &mc; 5581 5582 QL_PRINT_3(ha, "started\n"); 5583 5584 mcp->mb[0] = MBC_GET_PARAMETERS; 5585 mcp->mb[1] = READ_ASIC_TEMP << 8; 5586 mcp->out_mb = MBX_0_THRU_1; 5587 mcp->in_mb = MBX_0_THRU_1; 5588 mcp->timeout = MAILBOX_TOV; 5589 rval = ql_mailbox_command(ha, mcp); 5590 5591 /* Return config data. */ 5592 if (mr != NULL) { 5593 mr->mb[1] = mcp->mb[1]; 5594 } 5595 5596 if (rval != QL_SUCCESS) { 5597 EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]); 5598 } else { 5599 /*EMPTY*/ 5600 QL_PRINT_3(ha, "done\n"); 5601 } 5602 return (rval); 5603 } 5604 5605 /* 5606 * ql_write_serdes 5607 * Issue write FC serdes register mailbox command. 5608 * 5609 * Input: 5610 * ha: adapter state pointer. 5611 * mr: pointer for mailbox data. 5612 * 5613 * Returns: 5614 * ql local function return status code. 5615 * 5616 * Context: 5617 * Kernel context. 5618 */ 5619 int 5620 ql_write_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5621 { 5622 int rval; 5623 mbx_cmd_t mc = {0}; 5624 mbx_cmd_t *mcp = &mc; 5625 5626 QL_PRINT_3(ha, "started\n"); 5627 5628 mcp->mb[0] = MBC_WRITE_SERDES_REG; 5629 mcp->mb[1] = mr->mb[1]; 5630 mcp->mb[2] = mr->mb[2]; 5631 mcp->mb[3] = mr->mb[3]; 5632 mcp->mb[4] = mr->mb[4]; 5633 mcp->mb[5] = mr->mb[5]; 5634 mcp->mb[6] = mr->mb[6]; 5635 mcp->out_mb = MBX_0_THRU_6; 5636 mcp->in_mb = MBX_0; 5637 mcp->timeout = MAILBOX_TOV; 5638 rval = ql_mailbox_command(ha, mcp); 5639 5640 if (rval != QL_SUCCESS) { 5641 EL(ha, "failed, rval=%xh\n", rval); 5642 } else { 5643 /*EMPTY*/ 5644 QL_PRINT_3(ha, "done\n"); 5645 } 5646 5647 return (rval); 5648 } 5649 5650 /* 5651 * ql_read_serdes 5652 * Issue read FC serdes register mailbox command. 5653 * 5654 * Input: 5655 * ha: adapter state pointer. 5656 * mr: pointer for mailbox data. 5657 * 5658 * Returns: 5659 * ql local function return status code. 5660 * 5661 * Context: 5662 * Kernel context. 5663 */ 5664 int 5665 ql_read_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr) 5666 { 5667 int rval; 5668 mbx_cmd_t mc = {0}; 5669 mbx_cmd_t *mcp = &mc; 5670 5671 QL_PRINT_3(ha, "started\n"); 5672 5673 mcp->mb[0] = MBC_READ_SERDES_REG; 5674 mcp->mb[1] = mr->mb[1]; 5675 mcp->mb[2] = mr->mb[2]; 5676 mcp->mb[3] = mr->mb[3]; 5677 mcp->mb[4] = mr->mb[4]; 5678 mcp->mb[5] = mr->mb[5]; 5679 mcp->mb[6] = mr->mb[6]; 5680 mcp->out_mb = MBX_0_THRU_6; 5681 mcp->in_mb = MBX_0_THRU_6; 5682 mcp->timeout = MAILBOX_TOV; 5683 rval = ql_mailbox_command(ha, mcp); 5684 5685 /* Return mailbox data. */ 5686 mr->mb[0] = mcp->mb[0]; 5687 mr->mb[1] = mcp->mb[1]; 5688 mr->mb[2] = mcp->mb[2]; 5689 mr->mb[3] = mcp->mb[3]; 5690 mr->mb[4] = mcp->mb[4]; 5691 mr->mb[4] = mcp->mb[5]; 5692 mr->mb[4] = mcp->mb[6]; 5693 5694 if (rval != QL_SUCCESS) { 5695 EL(ha, "failed, rval=%xh", rval); 5696 } else { 5697 /*EMPTY*/ 5698 QL_PRINT_3(ha, "done\n"); 5699 } 5700 5701 return (rval); 5702 } 5703