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