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