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