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