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