Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
        
@@ -17,25 +17,25 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
 
-/* Copyright 2010 QLogic Corporation */
+/* Copyright 2015 QLogic Corporation */
 
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident   "Copyright 2010 QLogic Corporation; ql_init.c"
+#pragma ident   "Copyright 2015 QLogic Corporation; ql_init.c"
 
 /*
  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  *
  * ***********************************************************************
  * *                                                                    **
  * *                            NOTICE                                  **
- * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
+ * *            COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION              **
  * *                    ALL RIGHTS RESERVED                             **
  * *                                                                    **
  * ***********************************************************************
  *
  */
@@ -57,22 +57,22 @@
 /*
  * Local prototypes
  */
 static uint16_t ql_nvram_request(ql_adapter_state_t *, uint32_t);
 static int ql_nvram_24xx_config(ql_adapter_state_t *);
-static void ql_23_properties(ql_adapter_state_t *, nvram_t *);
-static void ql_24xx_properties(ql_adapter_state_t *, nvram_24xx_t *);
+static void ql_23_properties(ql_adapter_state_t *, ql_init_cb_t *);
+static void ql_24xx_properties(ql_adapter_state_t *, ql_init_24xx_cb_t *);
 static int ql_check_isp_firmware(ql_adapter_state_t *);
-static int ql_chip_diag(ql_adapter_state_t *);
 static int ql_load_flash_fw(ql_adapter_state_t *);
 static int ql_configure_loop(ql_adapter_state_t *);
 static int ql_configure_hba(ql_adapter_state_t *);
 static int ql_configure_fabric(ql_adapter_state_t *);
 static int ql_configure_device_d_id(ql_adapter_state_t *);
+static void ql_update_dev(ql_adapter_state_t *, uint32_t);
 static void ql_set_max_read_req(ql_adapter_state_t *);
 static void ql_configure_n_port_info(ql_adapter_state_t *);
-static void ql_clear_mcp(ql_adapter_state_t *);
+static void ql_reset_24xx_chip(ql_adapter_state_t *);
 static void ql_mps_reset(ql_adapter_state_t *);
 
 /*
  * ql_initialize_adapter
  *      Initialize board.
@@ -93,11 +93,11 @@
         class_svc_param_t       *class3_param;
         caddr_t                 msg;
         la_els_logi_t           *els = &ha->loginparams;
         int                     retries = 5;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started cfg=0x%llx\n", ha->cfg_flags);
 
         do {
                 /* Clear adapter flags. */
                 TASK_DAEMON_LOCK(ha);
                 ha->task_daemon_flags &= TASK_DAEMON_STOP_FLG |
@@ -134,54 +134,46 @@
                 /* Get NVRAM configuration if needed. */
                 if (ha->init_ctrl_blk.cb.version == 0) {
                         (void) ql_nvram_config(ha);
                 }
 
-                /* Set login parameters. */
-                if (CFG_IST(ha, CFG_CTRL_24258081)) {
-                        els->common_service.rx_bufsize = CHAR_TO_SHORT(
-                            ha->init_ctrl_blk.cb24.max_frame_length[0],
-                            ha->init_ctrl_blk.cb24.max_frame_length[1]);
-                        bcopy((void *)&ha->init_ctrl_blk.cb24.port_name[0],
-                            (void *)&els->nport_ww_name.raw_wwn[0], 8);
-                        bcopy((void *)&ha->init_ctrl_blk.cb24.node_name[0],
-                            (void *)&els->node_ww_name.raw_wwn[0], 8);
-                } else {
-                        els->common_service.rx_bufsize = CHAR_TO_SHORT(
-                            ha->init_ctrl_blk.cb.max_frame_length[0],
-                            ha->init_ctrl_blk.cb.max_frame_length[1]);
-                        bcopy((void *)&ha->init_ctrl_blk.cb.port_name[0],
-                            (void *)&els->nport_ww_name.raw_wwn[0], 8);
-                        bcopy((void *)&ha->init_ctrl_blk.cb.node_name[0],
-                            (void *)&els->node_ww_name.raw_wwn[0], 8);
-                }
-                bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
-                    strlen(QL_VERSION));
-
                 /* Determine which RISC code to use. */
                 if ((rval = ql_check_isp_firmware(ha)) != QL_SUCCESS) {
-                        if ((rval = ql_chip_diag(ha)) == QL_SUCCESS) {
+                        if (ha->dev_state != NX_DEV_READY) {
+                                EL(ha, "dev_state not ready, isp_abort_needed_2"
+                                    "\n");
+                                TASK_DAEMON_LOCK(ha);
+                                ha->task_daemon_flags |= ISP_ABORT_NEEDED;
+                                TASK_DAEMON_UNLOCK(ha);
+                                break;
+                        }
+                        if ((rval = ql_mbx_wrap_test(ha, NULL)) == QL_SUCCESS) {
                                 rval = ql_load_isp_firmware(ha);
                         }
                 }
 
                 if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
                     QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS) {
 
+                        ql_enable_intr(ha);
                         (void) ql_fw_ready(ha, ha->fwwait);
 
-                        if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
+                        if (!DRIVER_SUSPENDED(ha) &&
                             ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
                                 if (ha->topology & QL_LOOP_CONNECTION) {
                                         ha->state = ha->state | FC_STATE_LOOP;
                                         msg = "Loop ONLINE";
+                                        TASK_DAEMON_LOCK(ha);
                                         ha->task_daemon_flags |= STATE_ONLINE;
+                                        TASK_DAEMON_UNLOCK(ha);
                                 } else if (ha->topology & QL_P2P_CONNECTION) {
                                         ha->state = ha->state |
                                             FC_STATE_ONLINE;
                                         msg = "Link ONLINE";
+                                        TASK_DAEMON_LOCK(ha);
                                         ha->task_daemon_flags |= STATE_ONLINE;
+                                        TASK_DAEMON_UNLOCK(ha);
                                 } else {
                                         msg = "Unknown Link state";
                                 }
                         }
                 } else {
@@ -196,46 +188,56 @@
 
         } while (retries-- != 0 && ha->task_daemon_flags & ISP_ABORT_NEEDED);
 
         cmn_err(CE_NOTE, "!Qlogic %s(%d): %s", QL_NAME, ha->instance, msg);
 
-        /* Enable ISP interrupts and login parameters. */
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
-                ql_8021_enable_intrs(ha);
-        } else if (CFG_IST(ha, CFG_CTRL_242581)) {
-                WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
-        } else {
-                WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
+        /* Enable ISP interrupts if not already enabled. */
+        if (!(ha->flags & INTERRUPTS_ENABLED)) {
+                ql_enable_intr(ha);
         }
 
         ADAPTER_STATE_LOCK(ha);
-        ha->flags |= (INTERRUPTS_ENABLED | ONLINE);
+        ha->flags |= ONLINE;
         ADAPTER_STATE_UNLOCK(ha);
 
-        ha->task_daemon_flags &= ~(FC_STATE_CHANGE | RESET_MARKER_NEEDED |
+        /*
+         * Set flash write-protection.
+         */
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2) &&
+            ha->dev_state == NX_DEV_READY) {
+                ql_24xx_protect_flash(ha);
+        }
+
+        TASK_DAEMON_LOCK(ha);
+        ha->task_daemon_flags &= ~(FC_STATE_CHANGE | MARKER_NEEDED |
             COMMAND_WAIT_NEEDED);
+        TASK_DAEMON_UNLOCK(ha);
 
         /*
          * Setup login parameters.
          */
+        bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv, strlen(QL_VERSION));
+
         els->common_service.fcph_version = 0x2006;
         els->common_service.btob_credit = 3;
-        els->common_service.cmn_features = 0x8800;
+        els->common_service.cmn_features =
+            ha->topology & QL_N_PORT ? 0x8000 : 0x8800;
         els->common_service.conc_sequences = 0xff;
         els->common_service.relative_offset = 3;
         els->common_service.e_d_tov = 0x07d0;
 
         class3_param = (class_svc_param_t *)&els->class_3;
         class3_param->class_valid_svc_opt = 0x8800;
         class3_param->rcv_data_size = els->common_service.rx_bufsize;
         class3_param->conc_sequences = 0xff;
+        class3_param->open_sequences_per_exch = 1;
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -255,11 +257,11 @@
 ql_pci_sbus_config(ql_adapter_state_t *ha)
 {
         uint32_t        timer;
         uint16_t        cmd, w16;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                 w16 = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_REVISION));
                 EL(ha, "FPGA rev is %d.%d", (w16 & 0xf0) >> 4,
@@ -271,12 +273,15 @@
                  * want to make sure that all bits of interest to us
                  * are properly set in command register.
                  */
                 cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
                 cmd = (uint16_t)(cmd | PCI_COMM_IO | PCI_COMM_MAE |
-                    PCI_COMM_ME | PCI_COMM_MEMWR_INVAL |
-                    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
+                    PCI_COMM_ME | PCI_COMM_PARITY_DETECT |
+                    PCI_COMM_SERR_ENABLE);
+                if (ql_get_cap_ofst(ha, PCI_CAP_ID_PCIX)) {
+                        cmd = (uint16_t)(cmd | PCI_COMM_MEMWR_INVAL);
+                }
 
                 /*
                  * If this is a 2300 card and not 2312, reset the
                  * MEMWR_INVAL due to a bug in the 2300. Unfortunately, the
                  * 2310 also reports itself as a 2300 so we need to get the
@@ -326,11 +331,11 @@
                             != 0) {
                                 ql_pci_config_put8(ha, 0x66, 0xc2);
                         }
                 }
 
-                if (!(CFG_IST(ha, CFG_CTRL_8021)) &&
+                if (!(CFG_IST(ha, CFG_CTRL_82XX)) &&
                     ha->pci_max_read_req != 0) {
                         ql_set_max_read_req(ha);
                 }
 
                 ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
@@ -340,16 +345,18 @@
 
                 /* Set latency register. */
                 ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 0x40);
 
                 /* Reset expansion ROM address decode enable. */
+                if (!CFG_IST(ha, CFG_CTRL_278083)) {
                 w16 = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_ROM);
                 w16 = (uint16_t)(w16 & ~BIT_0);
                 ql_pci_config_put16(ha, PCI_CONF_ROM, w16);
         }
+        }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_10(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*
@@ -368,63 +375,68 @@
  */
 
 static void
 ql_set_max_read_req(ql_adapter_state_t *ha)
 {
+        int             ofst;
         uint16_t        read_req, w16;
         uint16_t        tmp = ha->pci_max_read_req;
 
-        if ((ha->device_id == 0x2422) ||
-            ((ha->device_id & 0xff00) == 0x2300)) {
+        QL_PRINT_3(ha, "started\n");
+
+        if ((ofst = ql_get_cap_ofst(ha, PCI_CAP_ID_PCIX))) {
+                ofst += PCI_PCIX_COMMAND;
+                QL_PRINT_10(ha, "PCI-X Command Reg = %xh\n", ofst);
                 /* check for vaild override value */
                 if (tmp == 512 || tmp == 1024 || tmp == 2048 ||
                     tmp == 4096) {
                         /* shift away the don't cares */
                         tmp = (uint16_t)(tmp >> 10);
                         /* convert bit pos to request value */
                         for (read_req = 0; tmp != 0; read_req++) {
                                 tmp = (uint16_t)(tmp >> 1);
                         }
-                        w16 = (uint16_t)ql_pci_config_get16(ha, 0x4e);
+                        w16 = (uint16_t)ql_pci_config_get16(ha, ofst);
                         w16 = (uint16_t)(w16 & ~(BIT_3 & BIT_2));
                         w16 = (uint16_t)(w16 | (read_req << 2));
-                        ql_pci_config_put16(ha, 0x4e, w16);
+                        ql_pci_config_put16(ha, ofst, w16);
                 } else {
                         EL(ha, "invalid parameter value for "
                             "'pci-max-read-request': %d; using system "
                             "default\n", tmp);
                 }
-        } else if ((ha->device_id == 0x2432) || ((ha->device_id & 0xff00) ==
-            0x2500) || (ha->device_id == 0x8432)) {
-                /* check for vaild override value */
+        } else if ((ofst = ql_get_cap_ofst(ha, PCI_CAP_ID_PCI_E))) {
+                ofst += PCI_PCIE_DEVICE_CONTROL;
+                QL_PRINT_10(ha, "PCI-E Device Control Reg = %xh\n", ofst);
                 if (tmp == 128 || tmp == 256 || tmp == 512 ||
                     tmp == 1024 || tmp == 2048 || tmp == 4096) {
                         /* shift away the don't cares */
                         tmp = (uint16_t)(tmp >> 8);
                         /* convert bit pos to request value */
                         for (read_req = 0; tmp != 0; read_req++) {
                                 tmp = (uint16_t)(tmp >> 1);
                         }
-                        w16 = (uint16_t)ql_pci_config_get16(ha, 0x54);
+                        w16 = (uint16_t)ql_pci_config_get16(ha, ofst);
                         w16 = (uint16_t)(w16 & ~(BIT_14 | BIT_13 |
                             BIT_12));
                         w16 = (uint16_t)(w16 | (read_req << 12));
-                        ql_pci_config_put16(ha, 0x54, w16);
+                        ql_pci_config_put16(ha, ofst, w16);
                 } else {
                         EL(ha, "invalid parameter value for "
                             "'pci-max-read-request': %d; using system "
                             "default\n", tmp);
                 }
         }
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * NVRAM configuration.
  *
  * Input:
  *      ha:             adapter state pointer.
- *      ha->hba_buf = request and response rings
+ *      ha->req_q[0]:   request ring
  *
  * Output:
  *      ha->init_ctrl_blk = initialization control block
  *      host adapters parameters in host adapter block
  *
@@ -439,29 +451,30 @@
 {
         uint32_t        cnt;
         caddr_t         dptr1, dptr2;
         ql_init_cb_t    *icb = &ha->init_ctrl_blk.cb;
         ql_ip_init_cb_t *ip_icb = &ha->ip_init_ctrl_blk.cb;
-        nvram_t         *nv = (nvram_t *)ha->request_ring_bp;
-        uint16_t        *wptr = (uint16_t *)ha->request_ring_bp;
+        nvram_t         *nv = (nvram_t *)ha->req_q[0]->req_ring.bp;
+        uint16_t        *wptr = (uint16_t *)ha->req_q[0]->req_ring.bp;
         uint8_t         chksum = 0;
         int             rval;
         int             idpromlen;
         char            idprombuf[32];
         uint32_t        start_addr;
+        la_els_logi_t   *els = &ha->loginparams;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 return (ql_nvram_24xx_config(ha));
         }
 
         start_addr = 0;
         if ((rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA)) ==
             QL_SUCCESS) {
                 /* Verify valid NVRAM checksum. */
-                for (cnt = 0; cnt < sizeof (nvram_t)/2; cnt++) {
+                for (cnt = 0; cnt < sizeof (nvram_t) / 2; cnt++) {
                         *wptr = (uint16_t)ql_get_nvram_word(ha,
                             (uint32_t)(cnt + start_addr));
                         chksum = (uint8_t)(chksum + (uint8_t)*wptr);
                         chksum = (uint8_t)(chksum + (uint8_t)(*wptr >> 8));
                         wptr++;
@@ -479,11 +492,11 @@
                     "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
                     nv->id[2], nv->id[3], ha->xioctl->fdesc.flash_size,
                     ha->subven_id, nv->nvram_version);
 
                 /* Don't print nvram message if it's an on-board 2200 */
-                if (!((CFG_IST(ha, CFG_CTRL_2200)) &&
+                if (!((CFG_IST(ha, CFG_CTRL_22XX)) &&
                     (ha->xioctl->fdesc.flash_size == 0))) {
                         cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed,"
                             " using driver defaults.", QL_NAME, ha->instance);
                 }
 
@@ -500,11 +513,11 @@
                 nv->max_frame_length[1] = 4;
 
                 /*
                  * Allow 2048 byte frames for 2300
                  */
-                if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+                if (CFG_IST(ha, CFG_CTRL_2363)) {
                         nv->max_frame_length[1] = 8;
                 }
                 nv->max_iocb_allocation[1] = 1;
                 nv->execution_throttle[0] = 16;
                 nv->login_retry_count = 8;
@@ -514,12 +527,12 @@
                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
                 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
                     DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
                     &idpromlen) != DDI_PROP_SUCCESS) {
 
-                        QL_PRINT_3(CE_CONT, "(%d): Unable to read idprom "
-                            "property\n", ha->instance);
+                        QL_PRINT_10(ha, "Unable to read idprom "
+                            "property\n");
                         cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
                             "property", QL_NAME, ha->instance);
 
                         nv->port_name[2] = 33;
                         nv->port_name[3] = 224;
@@ -537,11 +550,11 @@
                         nv->port_name[0] = (uint8_t)
                             (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
                 }
 
                 /* Don't print nvram message if it's an on-board 2200 */
-                if (!(CFG_IST(ha, CFG_CTRL_2200)) &&
+                if (!(CFG_IST(ha, CFG_CTRL_22XX)) &&
                     (ha->xioctl->fdesc.flash_size == 0)) {
                         cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using"
                             " default HBA parameters and temporary WWPN:"
                             " %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
                             ha->instance, nv->port_name[0], nv->port_name[1],
@@ -551,11 +564,11 @@
                 }
 
                 nv->login_timeout = 4;
 
                 /* Set default connection options for the 23xx to 2 */
-                if (!(CFG_IST(ha, CFG_CTRL_2200))) {
+                if (!(CFG_IST(ha, CFG_CTRL_22XX))) {
                         nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
                             BIT_5);
                 }
 
                 /*
@@ -568,39 +581,14 @@
                 nv->maximum_luns_per_target[0] = 8;
 
                 rval = QL_FUNCTION_FAILED;
         }
 
-        /* Check for adapter node name (big endian). */
-        for (cnt = 0; cnt < 8; cnt++) {
-                if (nv->node_name[cnt] != 0) {
-                        break;
-                }
-        }
-
-        /* Copy port name if no node name (big endian). */
-        if (cnt == 8) {
-                bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
-                nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
-                nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
-        }
-
         /* Reset initialization control blocks. */
         bzero((void *)icb, sizeof (ql_init_cb_t));
+        bzero((void *)ip_icb, sizeof (ql_ip_init_cb_t));
 
-        /* Get driver properties. */
-        ql_23_properties(ha, nv);
-
-        cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
-            "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
-            QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
-            nv->port_name[2], nv->port_name[3], nv->port_name[4],
-            nv->port_name[5], nv->port_name[6], nv->port_name[7],
-            nv->node_name[0], nv->node_name[1], nv->node_name[2],
-            nv->node_name[3], nv->node_name[4], nv->node_name[5],
-            nv->node_name[6], nv->node_name[7]);
-
         /*
          * Copy over NVRAM RISC parameter block
          * to initialization control block.
          */
         dptr1 = (caddr_t)icb;
@@ -613,15 +601,67 @@
 
         /* Copy 2nd half. */
         dptr1 = (caddr_t)&icb->add_fw_opt[0];
         cnt = (uint32_t)((uintptr_t)&icb->reserved_3[0] -
             (uintptr_t)&icb->add_fw_opt[0]);
-
         while (cnt-- != 0) {
                 *dptr1++ = *dptr2++;
         }
 
+        ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
+            nv->execution_throttle[1]);
+        ha->loop_reset_delay = nv->reset_delay;
+        ha->port_down_retry_count = nv->port_down_retry_count;
+        ha->maximum_luns_per_target = CHAR_TO_SHORT(
+            nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
+        if (ha->maximum_luns_per_target == 0) {
+                ha->maximum_luns_per_target++;
+        }
+        ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
+            nv->adapter_features[1]);
+
+        /* Check for adapter node name (big endian). */
+        for (cnt = 0; cnt < 8; cnt++) {
+                if (icb->node_name[cnt] != 0) {
+                        break;
+                }
+        }
+
+        /* Copy port name if no node name (big endian). */
+        if (cnt == 8) {
+                for (cnt = 0; cnt < 8; cnt++) {
+                        icb->node_name[cnt] = icb->port_name[cnt];
+                }
+                icb->node_name[0] = (uint8_t)(icb->node_name[0] & ~BIT_0);
+                icb->port_name[0] = (uint8_t)(icb->node_name[0] | BIT_0);
+        }
+
+        ADAPTER_STATE_LOCK(ha);
+        ha->cfg_flags &= ~(CFG_ENABLE_FULL_LIP_LOGIN | CFG_ENABLE_TARGET_RESET |
+            CFG_ENABLE_LIP_RESET | CFG_LOAD_FLASH_FW | CFG_FAST_TIMEOUT |
+            CFG_DISABLE_RISC_CODE_LOAD | CFG_ENABLE_FWEXTTRACE |
+            CFG_ENABLE_FWFCETRACE | CFG_SET_CACHE_LINE_SIZE_1 | CFG_LR_SUPPORT);
+        if (nv->host_p[0] & BIT_4) {
+                ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD;
+        }
+        if (nv->host_p[0] & BIT_5) {
+                ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1;
+        }
+        if (nv->host_p[1] & BIT_2) {
+                ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN;
+        }
+        if (nv->host_p[1] & BIT_3) {
+                ha->cfg_flags |= CFG_ENABLE_TARGET_RESET;
+        }
+        nv->adapter_features[0] & BIT_3 ?
+            (ha->flags |= MULTI_CHIP_ADAPTER) :
+            (ha->flags &= ~MULTI_CHIP_ADAPTER);
+        ADAPTER_STATE_UNLOCK(ha);
+
+        /* Get driver properties. */
+        ql_23_properties(ha, icb);
+
         /*
          * Setup driver firmware options.
          */
         icb->firmware_options[0] = (uint8_t)
             (icb->firmware_options[0] | BIT_6 | BIT_1);
@@ -629,11 +669,11 @@
         /*
          * There is no use enabling fast post for SBUS or 2300
          * Always enable 64bit addressing, except SBUS cards.
          */
         ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
-        if (CFG_IST(ha, (CFG_SBUS_CARD | CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_SBUS_CARD | CFG_CTRL_2363)) {
                 icb->firmware_options[0] = (uint8_t)
                     (icb->firmware_options[0] & ~BIT_3);
                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
                         icb->special_options[0] = (uint8_t)
                             (icb->special_options[0] | BIT_5);
@@ -651,95 +691,87 @@
             BIT_7 | BIT_6 | BIT_5 | BIT_2 | BIT_0);
         icb->firmware_options[0] = (uint8_t)
             (icb->firmware_options[0] & ~(BIT_5 | BIT_4));
         icb->firmware_options[1] = (uint8_t)
             (icb->firmware_options[1] & ~BIT_4);
-
+        if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
+                icb->firmware_options[1] = (uint8_t)
+                    (icb->firmware_options[1] | BIT_7 | BIT_6);
+                icb->add_fw_opt[1] = (uint8_t)
+                    (icb->add_fw_opt[1] | BIT_5 | BIT_4);
+        }
         icb->add_fw_opt[1] = (uint8_t)(icb->add_fw_opt[1] & ~(BIT_5 | BIT_4));
         icb->special_options[0] = (uint8_t)(icb->special_options[0] | BIT_1);
 
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 if ((icb->special_options[1] & 0x20) == 0) {
                         EL(ha, "50 ohm is not set\n");
                 }
         }
-        icb->execution_throttle[0] = 0xff;
-        icb->execution_throttle[1] = 0xff;
 
-        if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
-                icb->firmware_options[1] = (uint8_t)
-                    (icb->firmware_options[1] | BIT_7 | BIT_6);
-                icb->add_fw_opt[1] = (uint8_t)
-                    (icb->add_fw_opt[1] | BIT_5 | BIT_4);
-        }
-
         /*
          * Set host adapter parameters
          */
-        ADAPTER_STATE_LOCK(ha);
-        ha->nvram_version = nv->nvram_version;
-        ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
-            nv->adapter_features[1]);
+        /* Get adapter id string for Sun branded 23xx only */
+        if (CFG_IST(ha, CFG_CTRL_23XX) && nv->adapInfo[0] != 0) {
+                (void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
+                    nv->adapInfo);
+        }
 
-        nv->host_p[0] & BIT_4 ? (ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD) :
-            (ha->cfg_flags &= ~CFG_DISABLE_RISC_CODE_LOAD);
-        nv->host_p[0] & BIT_5 ? (ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1) :
-            (ha->cfg_flags &= ~CFG_SET_CACHE_LINE_SIZE_1);
-
-        nv->host_p[1] & BIT_1 ? (ha->cfg_flags |= CFG_ENABLE_LIP_RESET) :
-            (ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET);
-        nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
-            (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
-        nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
-            (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
-
-        nv->adapter_features[0] & BIT_3 ?
-            (ha->cfg_flags |= CFG_MULTI_CHIP_ADAPTER) :
-            (ha->cfg_flags &= ~CFG_MULTI_CHIP_ADAPTER);
-
-        ADAPTER_STATE_UNLOCK(ha);
-
-        ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
-            nv->execution_throttle[1]);
-        ha->loop_reset_delay = nv->reset_delay;
-        ha->port_down_retry_count = nv->port_down_retry_count;
         ha->r_a_tov = (uint16_t)(icb->login_timeout < R_A_TOV_DEFAULT ?
             R_A_TOV_DEFAULT : icb->login_timeout);
-        ha->maximum_luns_per_target = CHAR_TO_SHORT(
-            nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
-        if (ha->maximum_luns_per_target == 0) {
-                ha->maximum_luns_per_target++;
-        }
 
+        els->common_service.rx_bufsize = CHAR_TO_SHORT(
+            icb->max_frame_length[0], icb->max_frame_length[1]);
+        bcopy((void *)icb->port_name, (void *)els->nport_ww_name.raw_wwn, 8);
+        bcopy((void *)icb->node_name, (void *)els->node_ww_name.raw_wwn, 8);
+
+        cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
+            "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
+            QL_NAME, ha->instance,
+            els->nport_ww_name.raw_wwn[0], els->nport_ww_name.raw_wwn[1],
+            els->nport_ww_name.raw_wwn[2], els->nport_ww_name.raw_wwn[3],
+            els->nport_ww_name.raw_wwn[4], els->nport_ww_name.raw_wwn[5],
+            els->nport_ww_name.raw_wwn[6], els->nport_ww_name.raw_wwn[7],
+            els->node_ww_name.raw_wwn[0], els->node_ww_name.raw_wwn[1],
+            els->node_ww_name.raw_wwn[2], els->node_ww_name.raw_wwn[3],
+            els->node_ww_name.raw_wwn[4], els->node_ww_name.raw_wwn[5],
+            els->node_ww_name.raw_wwn[6], els->node_ww_name.raw_wwn[7]);
         /*
          * Setup ring parameters in initialization control block
          */
-        cnt = REQUEST_ENTRY_CNT;
+        cnt = ha->req_q[0]->req_entry_cnt;
         icb->request_q_length[0] = LSB(cnt);
         icb->request_q_length[1] = MSB(cnt);
-        cnt = RESPONSE_ENTRY_CNT;
+        cnt = ha->rsp_queues[0]->rsp_entry_cnt;
         icb->response_q_length[0] = LSB(cnt);
         icb->response_q_length[1] = MSB(cnt);
 
-        icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
-        icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
-        icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
-        icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
-        icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
-        icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
-        icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
-        icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
+        start_addr = ha->req_q[0]->req_ring.cookie.dmac_address;
+        icb->request_q_address[0] = LSB(LSW(start_addr));
+        icb->request_q_address[1] = MSB(LSW(start_addr));
+        icb->request_q_address[2] = LSB(MSW(start_addr));
+        icb->request_q_address[3] = MSB(MSW(start_addr));
 
-        icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
-        icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
-        icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
-        icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
-        icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
-        icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
-        icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
-        icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
+        start_addr = ha->req_q[0]->req_ring.cookie.dmac_notused;
+        icb->request_q_address[4] = LSB(LSW(start_addr));
+        icb->request_q_address[5] = MSB(LSW(start_addr));
+        icb->request_q_address[6] = LSB(MSW(start_addr));
+        icb->request_q_address[7] = MSB(MSW(start_addr));
 
+        start_addr = ha->rsp_queues[0]->rsp_ring.cookie.dmac_address;
+        icb->response_q_address[0] = LSB(LSW(start_addr));
+        icb->response_q_address[1] = MSB(LSW(start_addr));
+        icb->response_q_address[2] = LSB(MSW(start_addr));
+        icb->response_q_address[3] = MSB(MSW(start_addr));
+
+        start_addr = ha->rsp_queues[0]->rsp_ring.cookie.dmac_notused;
+        icb->response_q_address[4] = LSB(LSW(start_addr));
+        icb->response_q_address[5] = MSB(LSW(start_addr));
+        icb->response_q_address[6] = LSB(MSW(start_addr));
+        icb->response_q_address[7] = MSB(MSW(start_addr));
+
         /*
          * Setup IP initialization control block
          */
         ip_icb->version = IP_ICB_VERSION;
 
@@ -753,24 +785,27 @@
 
         cnt = RCVBUF_CONTAINER_CNT;
         ip_icb->queue_size[0] = LSB(cnt);
         ip_icb->queue_size[1] = MSB(cnt);
 
-        ip_icb->queue_address[0] = LSB(LSW(LSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[1] = MSB(LSW(LSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[2] = LSB(MSW(LSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[3] = MSB(MSW(LSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[4] = LSB(LSW(MSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[5] = MSB(LSW(MSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[6] = LSB(MSW(MSD(ha->rcvbuf_dvma)));
-        ip_icb->queue_address[7] = MSB(MSW(MSD(ha->rcvbuf_dvma)));
+        start_addr = ha->rcv_ring.cookie.dmac_address;
+        ip_icb->queue_address[0] = LSB(LSW(start_addr));
+        ip_icb->queue_address[1] = MSB(LSW(start_addr));
+        ip_icb->queue_address[2] = LSB(MSW(start_addr));
+        ip_icb->queue_address[3] = MSB(MSW(start_addr));
 
+        start_addr = ha->rcv_ring.cookie.dmac_notused;
+        ip_icb->queue_address[4] = LSB(LSW(start_addr));
+        ip_icb->queue_address[5] = MSB(LSW(start_addr));
+        ip_icb->queue_address[6] = LSB(MSW(start_addr));
+        ip_icb->queue_address[7] = MSB(MSW(start_addr));
+
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -792,18 +827,18 @@
 ql_get_nvram_word(ql_adapter_state_t *ha, uint32_t address)
 {
         uint32_t        nv_cmd;
         uint16_t        rval;
 
-        QL_PRINT_4(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_4(ha, "started\n");
 
         nv_cmd = address << 16;
         nv_cmd = nv_cmd | NV_READ_OP;
 
         rval = (uint16_t)ql_nvram_request(ha, nv_cmd);
 
-        QL_PRINT_4(CE_CONT, "(%d): NVRAM data = %xh\n", ha->instance, rval);
+        QL_PRINT_4(ha, "NVRAM data = %xh\n", rval);
 
         return (rval);
 }
 
 /*
@@ -843,11 +878,11 @@
         }
 
         /* Read data from NVRAM. */
 
         for (cnt = 0; cnt < 16; cnt++) {
-                WRT16_IO_REG(ha, nvram, NV_SELECT+NV_CLOCK);
+                WRT16_IO_REG(ha, nvram, NV_SELECT + NV_CLOCK);
                 ql_nv_delay();
                 data <<= 1;
                 reg_data = RD16_IO_REG(ha, nvram);
                 if (reg_data & NV_DATA_IN) {
                         data = (uint16_t)(data | BIT_0);
@@ -885,11 +920,11 @@
  * ql_nvram_24xx_config
  *      ISP2400 nvram.
  *
  * Input:
  *      ha:             adapter state pointer.
- *      ha->hba_buf = request and response rings
+ *      ha->req_q[0]:   request ring
  *
  * Output:
  *      ha->init_ctrl_blk = initialization control block
  *      host adapters parameters in host adapter block
  *
@@ -900,11 +935,12 @@
  *      Kernel context.
  */
 int
 ql_nvram_24xx_config(ql_adapter_state_t *ha)
 {
-        uint32_t                index, addr, chksum, saved_chksum;
+        uint32_t                index, addr;
+        uint32_t                chksum = 0, saved_chksum = 0;
         uint32_t                *longptr;
         nvram_24xx_t            nvram;
         int                     idpromlen;
         char                    idprombuf[32];
         caddr_t                 src, dst;
@@ -912,12 +948,13 @@
         int                     rval;
         nvram_24xx_t            *nv = (nvram_24xx_t *)&nvram;
         ql_init_24xx_cb_t       *icb =
             (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
         ql_ip_init_24xx_cb_t    *ip_icb = &ha->ip_init_ctrl_blk.cb24;
+        la_els_logi_t           *els = &ha->loginparams;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         if ((rval = ql_lock_nvram(ha, &addr, LNF_NVRAM_DATA)) == QL_SUCCESS) {
 
                 /* Get NVRAM data and calculate checksum. */
                 longptr = (uint32_t *)nv;
@@ -942,11 +979,10 @@
             nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
             (nv->nvram_version[0] | nv->nvram_version[1]) == 0) {
 
                 cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed, using "
                     "driver defaults.", QL_NAME, ha->instance);
-
                 EL(ha, "failed, rval=%xh, checksum=%xh, id=%c%c%c%c, "
                     "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
                     nv->id[2], nv->id[3], CHAR_TO_SHORT(nv->nvram_version[0],
                     nv->nvram_version[1]));
 
@@ -1019,11 +1055,11 @@
                 nv->reset_delay = 5;
                 nv->max_luns_per_target[0] = 128;
                 nv->port_down_retry_count[0] = 30;
                 nv->link_down_timeout[0] = 30;
 
-                if (CFG_IST(ha, CFG_CTRL_8081)) {
+                if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
                         nv->firmware_options_3[2] = BIT_4;
                         nv->feature_mask_l[0] = 9;
                         nv->ext_blk.version[0] = 1;
                         nv->ext_blk.fcf_vlan_match = 1;
                         nv->ext_blk.fcf_vlan_id[0] = LSB(1002);
@@ -1036,39 +1072,13 @@
                 }
 
                 rval = QL_FUNCTION_FAILED;
         }
 
-        /* Check for adapter node name (big endian). */
-        for (index = 0; index < 8; index++) {
-                if (nv->node_name[index] != 0) {
-                        break;
-                }
-        }
-
-        /* Copy port name if no node name (big endian). */
-        if (index == 8) {
-                bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
-                nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
-                nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
-        }
-
         /* Reset initialization control blocks. */
         bzero((void *)icb, sizeof (ql_init_24xx_cb_t));
 
-        /* Get driver properties. */
-        ql_24xx_properties(ha, nv);
-
-        cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
-            "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
-            QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
-            nv->port_name[2], nv->port_name[3], nv->port_name[4],
-            nv->port_name[5], nv->port_name[6], nv->port_name[7],
-            nv->node_name[0], nv->node_name[1], nv->node_name[2],
-            nv->node_name[3], nv->node_name[4], nv->node_name[5],
-            nv->node_name[6], nv->node_name[7]);
-
         /*
          * Copy over NVRAM Firmware Initialization Control Block.
          */
         dst = (caddr_t)icb;
         src = (caddr_t)&nv->version;
@@ -1080,22 +1090,29 @@
         icb->login_retry_count[0] = nv->login_retry_count[0];
         icb->login_retry_count[1] = nv->login_retry_count[1];
         icb->link_down_on_nos[0] = nv->link_down_on_nos[0];
         icb->link_down_on_nos[1] = nv->link_down_on_nos[1];
 
+        /* Copy 2nd half. */
         dst = (caddr_t)&icb->interrupt_delay_timer;
         src = (caddr_t)&nv->interrupt_delay_timer;
         index = (uint32_t)((uintptr_t)&icb->qos -
             (uintptr_t)&icb->interrupt_delay_timer);
         while (index--) {
                 *dst++ = *src++;
         }
 
-        /*
-         * Setup driver firmware options.
-         */
-        if (CFG_IST(ha, CFG_CTRL_8081)) {
+        ha->execution_throttle = 16;
+        ha->loop_reset_delay = nv->reset_delay;
+        ha->port_down_retry_count = CHAR_TO_SHORT(nv->port_down_retry_count[0],
+            nv->port_down_retry_count[1]);
+        ha->maximum_luns_per_target = CHAR_TO_SHORT(
+            nv->max_luns_per_target[0], nv->max_luns_per_target[1]);
+        if (ha->maximum_luns_per_target == 0) {
+                ha->maximum_luns_per_target++;
+        }
+        if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
                 dst = (caddr_t)icb->enode_mac_addr;
                 src = (caddr_t)nv->fw.isp8001.e_node_mac_addr;
                 index = sizeof (nv->fw.isp8001.e_node_mac_addr);
                 while (index--) {
                         *dst++ = *src++;
@@ -1108,11 +1125,49 @@
                 }
                 EL(ha, "e_node_mac_addr=%02x-%02x-%02x-%02x-%02x-%02x\n",
                     icb->enode_mac_addr[0], icb->enode_mac_addr[1],
                     icb->enode_mac_addr[2], icb->enode_mac_addr[3],
                     icb->enode_mac_addr[4], icb->enode_mac_addr[5]);
-        } else {
+        }
+
+        /* Check for adapter node name (big endian). */
+        for (index = 0; index < 8; index++) {
+                if (icb->node_name[index] != 0) {
+                        break;
+                }
+        }
+
+        /* Copy port name if no node name (big endian). */
+        if (index == 8) {
+                for (index = 0; index < 8; index++) {
+                        icb->node_name[index] = icb->port_name[index];
+                }
+                icb->node_name[0] = (uint8_t)(icb->node_name[0] & ~BIT_0);
+                icb->port_name[0] = (uint8_t)(icb->node_name[0] | BIT_0);
+        }
+
+        ADAPTER_STATE_LOCK(ha);
+        ha->cfg_flags &= ~(CFG_ENABLE_FULL_LIP_LOGIN | CFG_ENABLE_TARGET_RESET |
+            CFG_ENABLE_LIP_RESET | CFG_LOAD_FLASH_FW | CFG_FAST_TIMEOUT |
+            CFG_DISABLE_RISC_CODE_LOAD | CFG_ENABLE_FWEXTTRACE |
+            CFG_ENABLE_FWFCETRACE | CFG_SET_CACHE_LINE_SIZE_1 | CFG_LR_SUPPORT);
+        if (nv->host_p[1] & BIT_2) {
+                ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN;
+        }
+        if (nv->host_p[1] & BIT_3) {
+                ha->cfg_flags |= CFG_ENABLE_TARGET_RESET;
+        }
+        ha->flags &= ~MULTI_CHIP_ADAPTER;
+        ADAPTER_STATE_UNLOCK(ha);
+
+        /* Get driver properties. */
+        ql_24xx_properties(ha, icb);
+
+        /*
+         * Setup driver firmware options.
+         */
+        if (!CFG_IST(ha, CFG_FCOE_SUPPORT)) {
                 icb->firmware_options_1[0] = (uint8_t)
                     (icb->firmware_options_1[0] | BIT_1);
                 icb->firmware_options_1[1] = (uint8_t)
                     (icb->firmware_options_1[1] | BIT_5 | BIT_2);
                 icb->firmware_options_3[0] = (uint8_t)
@@ -1129,56 +1184,37 @@
                     (icb->firmware_options_2[1] | BIT_4);
         } else {
                 icb->firmware_options_2[1] = (uint8_t)
                     (icb->firmware_options_2[1] & ~BIT_4);
         }
-
         icb->firmware_options_3[0] = (uint8_t)(icb->firmware_options_3[0] &
             ~BIT_7);
 
-        /* enable special N port 2 N port login behaviour */
-        if (CFG_IST(ha, CFG_CTRL_2425)) {
-                icb->firmware_options_3[1] =
-                    (uint8_t)(icb->firmware_options_3[1] | BIT_0);
-        }
-
-        icb->execution_throttle[0] = 0xff;
-        icb->execution_throttle[1] = 0xff;
-
         /*
          * Set host adapter parameters
          */
+        w1 = CHAR_TO_SHORT(icb->login_timeout[0], icb->login_timeout[1]);
+        ha->r_a_tov = (uint16_t)(w1 < R_A_TOV_DEFAULT ? R_A_TOV_DEFAULT : w1);
+
         ADAPTER_STATE_LOCK(ha);
-        ha->nvram_version = CHAR_TO_SHORT(nv->nvram_version[0],
-            nv->nvram_version[1]);
-        nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
-            (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
-        nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
-            (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
-        ha->cfg_flags &= ~(CFG_DISABLE_RISC_CODE_LOAD | CFG_LR_SUPPORT |
-            CFG_SET_CACHE_LINE_SIZE_1 | CFG_MULTI_CHIP_ADAPTER);
         ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
         if (CFG_IST(ha, CFG_CTRL_81XX) && nv->enhanced_features[0] & BIT_0) {
                 ha->cfg_flags |= CFG_LR_SUPPORT;
         }
         ADAPTER_STATE_UNLOCK(ha);
 
-        ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
-            nv->execution_throttle[1]);
-        ha->loop_reset_delay = nv->reset_delay;
-        ha->port_down_retry_count = CHAR_TO_SHORT(nv->port_down_retry_count[0],
-            nv->port_down_retry_count[1]);
-        w1 = CHAR_TO_SHORT(icb->login_timeout[0], icb->login_timeout[1]);
-        ha->r_a_tov = (uint16_t)(w1 < R_A_TOV_DEFAULT ? R_A_TOV_DEFAULT : w1);
-        ha->maximum_luns_per_target = CHAR_TO_SHORT(
-            nv->max_luns_per_target[0], nv->max_luns_per_target[1]);
-        if (ha->maximum_luns_per_target == 0) {
-                ha->maximum_luns_per_target++;
+        /* Queue shadowing */
+        if (ha->flags & QUEUE_SHADOW_PTRS) {
+                icb->firmware_options_2[3] = (uint8_t)
+                    (icb->firmware_options_2[3] | BIT_6 | BIT_5);
+        } else {
+                icb->firmware_options_2[3] = (uint8_t)
+                    (icb->firmware_options_2[3] | ~(BIT_6 | BIT_5));
         }
 
         /* ISP2422 Serial Link Control */
-        if (CFG_IST(ha, CFG_CTRL_2422)) {
+        if (CFG_IST(ha, CFG_CTRL_24XX)) {
                 ha->serdes_param[0] = CHAR_TO_SHORT(nv->fw.isp2400.swing_opt[0],
                     nv->fw.isp2400.swing_opt[1]);
                 ha->serdes_param[1] = CHAR_TO_SHORT(nv->fw.isp2400.swing_1g[0],
                     nv->fw.isp2400.swing_1g[1]);
                 ha->serdes_param[2] = CHAR_TO_SHORT(nv->fw.isp2400.swing_2g[0],
@@ -1185,38 +1221,60 @@
                     nv->fw.isp2400.swing_2g[1]);
                 ha->serdes_param[3] = CHAR_TO_SHORT(nv->fw.isp2400.swing_4g[0],
                     nv->fw.isp2400.swing_4g[1]);
         }
 
+        els->common_service.rx_bufsize = CHAR_TO_SHORT(
+            icb->max_frame_length[0], icb->max_frame_length[1]);
+        bcopy((void *)icb->port_name, (void *)els->nport_ww_name.raw_wwn, 8);
+        bcopy((void *)icb->node_name, (void *)els->node_ww_name.raw_wwn, 8);
+
+        cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
+            "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
+            QL_NAME, ha->instance,
+            els->nport_ww_name.raw_wwn[0], els->nport_ww_name.raw_wwn[1],
+            els->nport_ww_name.raw_wwn[2], els->nport_ww_name.raw_wwn[3],
+            els->nport_ww_name.raw_wwn[4], els->nport_ww_name.raw_wwn[5],
+            els->nport_ww_name.raw_wwn[6], els->nport_ww_name.raw_wwn[7],
+            els->node_ww_name.raw_wwn[0], els->node_ww_name.raw_wwn[1],
+            els->node_ww_name.raw_wwn[2], els->node_ww_name.raw_wwn[3],
+            els->node_ww_name.raw_wwn[4], els->node_ww_name.raw_wwn[5],
+            els->node_ww_name.raw_wwn[6], els->node_ww_name.raw_wwn[7]);
         /*
          * Setup ring parameters in initialization control block
          */
-        w1 = REQUEST_ENTRY_CNT;
+        w1 = ha->req_q[0]->req_entry_cnt;
         icb->request_q_length[0] = LSB(w1);
         icb->request_q_length[1] = MSB(w1);
-        w1 = RESPONSE_ENTRY_CNT;
+        w1 = ha->rsp_queues[0]->rsp_entry_cnt;
         icb->response_q_length[0] = LSB(w1);
         icb->response_q_length[1] = MSB(w1);
 
-        icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
-        icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
-        icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
-        icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
-        icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
-        icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
-        icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
-        icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
+        addr = ha->req_q[0]->req_ring.cookie.dmac_address;
+        icb->request_q_address[0] = LSB(LSW(addr));
+        icb->request_q_address[1] = MSB(LSW(addr));
+        icb->request_q_address[2] = LSB(MSW(addr));
+        icb->request_q_address[3] = MSB(MSW(addr));
 
-        icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
-        icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
-        icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
-        icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
-        icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
-        icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
-        icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
-        icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
+        addr = ha->req_q[0]->req_ring.cookie.dmac_notused;
+        icb->request_q_address[4] = LSB(LSW(addr));
+        icb->request_q_address[5] = MSB(LSW(addr));
+        icb->request_q_address[6] = LSB(MSW(addr));
+        icb->request_q_address[7] = MSB(MSW(addr));
 
+        addr = ha->rsp_queues[0]->rsp_ring.cookie.dmac_address;
+        icb->response_q_address[0] = LSB(LSW(addr));
+        icb->response_q_address[1] = MSB(LSW(addr));
+        icb->response_q_address[2] = LSB(MSW(addr));
+        icb->response_q_address[3] = MSB(MSW(addr));
+
+        addr = ha->rsp_queues[0]->rsp_ring.cookie.dmac_notused;
+        icb->response_q_address[4] = LSB(LSW(addr));
+        icb->response_q_address[5] = MSB(LSW(addr));
+        icb->response_q_address[6] = LSB(MSW(addr));
+        icb->response_q_address[7] = MSB(MSW(addr));
+
         /*
          * Setup IP initialization control block
          */
         ip_icb->version = IP_ICB_24XX_VERSION;
 
@@ -1225,11 +1283,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -1252,10 +1310,12 @@
 int
 ql_lock_nvram(ql_adapter_state_t *ha, uint32_t *addr, uint32_t flags)
 {
         int     i;
 
+        QL_PRINT_3(ha, "started\n");
+
         if ((flags & LNF_NVRAM_DATA) && (flags & LNF_VPD_DATA)) {
                 EL(ha, "invalid options for function");
                 return (QL_FUNCTION_FAILED);
         }
 
@@ -1283,11 +1343,11 @@
                 if ((RD16_IO_REG(ha, host_to_host_sema) & 1) == 0) {
                         cmn_err(CE_WARN, "%s(%d): unable to get NVRAM lock",
                             QL_NAME, ha->instance);
                         return (QL_FUNCTION_FAILED);
                 }
-        } else if (CFG_IST(ha, CFG_CTRL_2422)) {
+        } else if (CFG_IST(ha, CFG_CTRL_24XX)) {
                 if (flags & LNF_VPD_DATA) {
                         *addr = NVRAM_DATA_ADDR | ha->flash_vpd_addr;
                 } else if (flags & LNF_NVRAM_DATA) {
                         *addr = NVRAM_DATA_ADDR | ha->flash_nvram_addr;
                 } else {
@@ -1294,11 +1354,11 @@
                         EL(ha, "invalid 2422 option for HBA");
                         return (QL_FUNCTION_FAILED);
                 }
 
                 GLOBAL_HW_LOCK();
-        } else if (CFG_IST(ha, CFG_CTRL_258081)) {
+        } else if (CFG_IST(ha, CFG_CTRL_252780818283)) {
                 if (flags & LNF_VPD_DATA) {
                         *addr = ha->flash_data_addr | ha->flash_vpd_addr;
                 } else if (flags & LNF_NVRAM_DATA) {
                         *addr = ha->flash_data_addr | ha->flash_nvram_addr;
                 } else {
@@ -1314,10 +1374,12 @@
                 }
                 *addr = 0;
                 GLOBAL_HW_LOCK();
         }
 
+        QL_PRINT_3(ha, "done\n");
+
         return (QL_SUCCESS);
 }
 
 /*
  * ql_release_nvram
@@ -1330,16 +1392,20 @@
  *      Kernel context.
  */
 void
 ql_release_nvram(ql_adapter_state_t *ha)
 {
+        QL_PRINT_3(ha, "started\n");
+
         if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
                 /* Release resource lock */
                 WRT16_IO_REG(ha, host_to_host_sema, 0);
         } else {
                 GLOBAL_HW_UNLOCK();
         }
+
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_23_properties
  *      Copies driver properties to NVRAM or adapter structure.
@@ -1348,206 +1414,203 @@
  *      completely from administrators. Knowledgeable folks can
  *      override the default values using driver.conf
  *
  * Input:
  *      ha:     adapter state pointer.
- *      nv:     NVRAM structure pointer.
+ *      icb:    Init control block structure pointer.
  *
  * Context:
  *      Kernel context.
  */
 static void
-ql_23_properties(ql_adapter_state_t *ha, nvram_t *nv)
+ql_23_properties(ql_adapter_state_t *ha, ql_init_cb_t *icb)
 {
         uint32_t        data, cnt;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Get frame payload size. */
         if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
                 data = 2048;
         }
         if (data == 512 || data == 1024 || data == 2048) {
-                nv->max_frame_length[0] = LSB(data);
-                nv->max_frame_length[1] = MSB(data);
+                icb->max_frame_length[0] = LSB(data);
+                icb->max_frame_length[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'max-frame-length': "
                     "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
-                    nv->max_frame_length[0], nv->max_frame_length[1]));
+                    icb->max_frame_length[0], icb->max_frame_length[1]));
         }
 
         /* Get max IOCB allocation. */
-        nv->max_iocb_allocation[0] = 0;
-        nv->max_iocb_allocation[1] = 1;
+        icb->max_iocb_allocation[0] = 0;
+        icb->max_iocb_allocation[1] = 1;
 
         /* Get execution throttle. */
         if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
                 data = 32;
         }
         if (data != 0 && data < 65536) {
-                nv->execution_throttle[0] = LSB(data);
-                nv->execution_throttle[1] = MSB(data);
+                icb->execution_throttle[0] = LSB(data);
+                icb->execution_throttle[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'execution-throttle': "
                     "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
-                    nv->execution_throttle[0], nv->execution_throttle[1]));
+                    icb->execution_throttle[0], icb->execution_throttle[1]));
         }
 
         /* Get Login timeout. */
         if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
                 data = 3;
         }
         if (data < 256) {
-                nv->login_timeout = (uint8_t)data;
+                icb->login_timeout = (uint8_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'login-timeout': "
-                    "%d; using nvram value of %d\n", data, nv->login_timeout);
+                    "%d; using nvram value of %d\n", data, icb->login_timeout);
         }
 
         /* Get retry count. */
         if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
                 data = 4;
         }
         if (data < 256) {
-                nv->login_retry_count = (uint8_t)data;
+                icb->login_retry_count = (uint8_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'login-retry-count': "
                     "%d; using nvram value of %d\n", data,
-                    nv->login_retry_count);
+                    icb->login_retry_count);
         }
 
         /* Get adapter hard loop ID enable. */
         data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
         if (data == 0) {
-                nv->firmware_options[0] =
-                    (uint8_t)(nv->firmware_options[0] & ~BIT_0);
+                icb->firmware_options[0] =
+                    (uint8_t)(icb->firmware_options[0] & ~BIT_0);
         } else if (data == 1) {
-                nv->firmware_options[0] =
-                    (uint8_t)(nv->firmware_options[0] | BIT_0);
+                icb->firmware_options[0] =
+                    (uint8_t)(icb->firmware_options[0] | BIT_0);
         } else if (data != 0xffffffff) {
                 EL(ha, "invalid parameter value for "
                     "'enable-adapter-hard-loop-ID': %d; using nvram value "
-                    "of %d\n", data, nv->firmware_options[0] & BIT_0 ? 1 : 0);
+                    "of %d\n", data, icb->firmware_options[0] & BIT_0 ? 1 : 0);
         }
 
         /* Get adapter hard loop ID. */
         data =  ql_get_prop(ha, "adapter-hard-loop-ID");
         if (data < 126) {
-                nv->hard_address[0] = (uint8_t)data;
+                icb->hard_address[0] = (uint8_t)data;
         } else if (data != 0xffffffff) {
                 EL(ha, "invalid parameter value for 'adapter-hard-loop-ID': "
                     "%d; using nvram value of %d\n",
-                    data, nv->hard_address[0]);
+                    data, icb->hard_address[0]);
         }
 
         /* Get LIP reset. */
         if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
             0xffffffff) {
                 data = 0;
         }
         if (data == 0) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_1);
+                ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET;
         } else if (data == 1) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_1);
+                ha->cfg_flags |= CFG_ENABLE_LIP_RESET;
         } else {
                 EL(ha, "invalid parameter value for "
                     "'enable-LIP-reset-on-bus-reset': %d; using nvram value "
-                    "of %d\n", data, nv->host_p[1] & BIT_1 ? 1 : 0);
+                    "of %d\n", data,
+                    CFG_IST(ha, CFG_ENABLE_LIP_RESET) ? 1 : 0);
         }
 
         /* Get LIP full login. */
         if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
             0xffffffff) {
                 data = 1;
         }
         if (data == 0) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
+                ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN;
         } else if (data == 1) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
+                ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN;
         } else {
                 EL(ha, "invalid parameter value for "
                     "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
-                    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
+                    "value of %d\n", data,
+                    CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN) ? 1 : 0);
         }
 
         /* Get target reset. */
         if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
             0xffffffff) {
                 data = 0;
         }
         if (data == 0) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
+                ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET;
         } else if (data == 1) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
+                ha->cfg_flags |= CFG_ENABLE_TARGET_RESET;
         } else {
                 EL(ha, "invalid parameter value for "
                     "'enable-target-reset-on-bus-reset': %d; using nvram "
-                    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
+                    "value of %d", data,
+                    CFG_IST(ha, CFG_ENABLE_TARGET_RESET) ? 1 : 0);
         }
 
         /* Get reset delay. */
         if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
                 data = 5;
         }
         if (data != 0 && data < 256) {
-                nv->reset_delay = (uint8_t)data;
+                ha->loop_reset_delay = (uint8_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'reset-delay': %d; "
-                    "using nvram value of %d", data, nv->reset_delay);
+                    "using nvram value of %d", data, ha->loop_reset_delay);
         }
 
         /* Get port down retry count. */
         if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
                 data = 8;
         }
         if (data < 256) {
-                nv->port_down_retry_count = (uint8_t)data;
+                ha->port_down_retry_count = (uint8_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'port-down-retry-count':"
                     " %d; using nvram value of %d\n", data,
-                    nv->port_down_retry_count);
+                    ha->port_down_retry_count);
         }
 
         /* Get connection mode setting. */
         if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
                 data = 2;
         }
-        cnt = CFG_IST(ha, CFG_CTRL_2200) ? 3 : 2;
+        cnt = CFG_IST(ha, CFG_CTRL_22XX) ? 3 : 2;
         if (data <= cnt) {
-                nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] &
+                icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] &
                     ~(BIT_6 | BIT_5 | BIT_4));
-                nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
+                icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] |
                     (uint8_t)(data << 4));
         } else {
                 EL(ha, "invalid parameter value for 'connection-options': "
                     "%d; using nvram value of %d\n", data,
-                    (nv->add_fw_opt[0] >> 4) & 0x3);
+                    (icb->add_fw_opt[0] >> 4) & 0x3);
         }
 
         /* Get data rate setting. */
-        if ((CFG_IST(ha, CFG_CTRL_2200)) == 0) {
+        if ((CFG_IST(ha, CFG_CTRL_22XX)) == 0) {
                 if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
                         data = 2;
                 }
                 if (data < 3) {
-                        nv->special_options[1] = (uint8_t)
-                            (nv->special_options[1] & 0x3f);
-                        nv->special_options[1] = (uint8_t)
-                            (nv->special_options[1] | (uint8_t)(data << 6));
+                        icb->special_options[1] = (uint8_t)
+                            (icb->special_options[1] & 0x3f);
+                        icb->special_options[1] = (uint8_t)
+                            (icb->special_options[1] | (uint8_t)(data << 6));
                 } else {
                         EL(ha, "invalid parameter value for 'fc-data-rate': "
                             "%d; using nvram value of %d\n", data,
-                            (nv->special_options[1] >> 6) & 0x3);
+                            (icb->special_options[1] >> 6) & 0x3);
                 }
         }
 
-        /* Get adapter id string for Sun branded 23xx only */
-        if ((CFG_IST(ha, CFG_CTRL_2300)) && nv->adapInfo[0] != 0) {
-                (void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
-                    nv->adapInfo);
-        }
-
         /* Get IP FW container count. */
         ha->ip_init_ctrl_blk.cb.cc[0] = LSB(ql_ip_buffer_count);
         ha->ip_init_ctrl_blk.cb.cc[1] = MSB(ql_ip_buffer_count);
 
         /* Get IP low water mark. */
@@ -1562,11 +1625,11 @@
 
         ql_common_properties(ha);
 
         ADAPTER_STATE_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_common_properties
  *      Driver properties adapter structure.
@@ -1584,38 +1647,12 @@
 void
 ql_common_properties(ql_adapter_state_t *ha)
 {
         uint32_t        data;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
-        /* Get extended logging trace buffer size. */
-        if ((data = ql_get_prop(ha, "set-ext-log-buffer-size")) !=
-            0xffffffff && data != 0) {
-                char            *new_trace;
-                uint32_t        new_size;
-
-                if (ha->el_trace_desc->trace_buffer != NULL) {
-                        new_size = 1024 * data;
-                        new_trace = (char *)kmem_zalloc(new_size, KM_SLEEP);
-
-                        if (new_trace == NULL) {
-                                cmn_err(CE_WARN, "%s(%d): can't get new"
-                                    " trace buffer",
-                                    QL_NAME, ha->instance);
-                        } else {
-                                /* free the previous */
-                                kmem_free(ha->el_trace_desc->trace_buffer,
-                                    ha->el_trace_desc->trace_buffer_size);
-                                /* Use the new one */
-                                ha->el_trace_desc->trace_buffer = new_trace;
-                                ha->el_trace_desc->trace_buffer_size = new_size;
-                        }
-                }
-
-        }
-
         /* Get extended logging enable. */
         if ((data = ql_get_prop(ha, "extended-logging")) == 0xffffffff ||
             data == 0) {
                 ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
         } else if (data == 1) {
@@ -1624,23 +1661,10 @@
                 EL(ha, "invalid parameter value for 'extended-logging': %d;"
                     " using default value of 0\n", data);
                 ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
         }
 
-        /* Get extended logging trace disable. */
-        if ((data = ql_get_prop(ha, "disable-extended-logging-trace")) ==
-            0xffffffff || data == 0) {
-                ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
-        } else if (data == 1) {
-                ha->cfg_flags |= CFG_DISABLE_EXTENDED_LOGGING_TRACE;
-        } else {
-                EL(ha, "invalid parameter value for "
-                    "'disable-extended-logging-trace': %d;"
-                    " using default value of 0\n", data);
-                ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
-        }
-
         /* Get FCP 2 Error Recovery. */
         if ((data = ql_get_prop(ha, "enable-FCP-2-error-recovery")) ==
             0xffffffff || data == 1) {
                 ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
         } else if (data == 0) {
@@ -1745,15 +1769,25 @@
         if ((data = ql_get_prop(ha, "pci-max-read-request")) != 0xffffffff &&
             data != 0) {
                 ha->pci_max_read_req = (uint16_t)(data);
         }
 
+        /* Get the plogi retry params overrides. */
+        if ((data = ql_get_prop(ha, "plogi_params_retry_count")) !=
+            0xffffffff && data != 0) {
+                ha->plogi_params->retry_cnt = (uint32_t)(data);
+        }
+        if ((data = ql_get_prop(ha, "plogi_params_retry_delay")) !=
+            0xffffffff && data != 0) {
+                ha->plogi_params->retry_dly_usec = (uint32_t)(data);
+        }
+
         /*
          * Set default fw wait, adjusted for slow FCF's.
          * Revisit when FCF's as fast as FC switches.
          */
-        ha->fwwait = (uint8_t)(CFG_IST(ha, CFG_CTRL_8081) ? 45 : 10);
+        ha->fwwait = (uint8_t)(CFG_IST(ha, CFG_FCOE_SUPPORT) ? 45 : 10);
         /* Get the attach fw_ready override value. */
         if ((data = ql_get_prop(ha, "init-loop-sync-wait")) != 0xffffffff) {
                 if (data > 0 && data <= 240) {
                         ha->fwwait = (uint8_t)data;
                 } else {
@@ -1761,11 +1795,48 @@
                             "'init-loop-sync-wait': %d; using default "
                             "value of %d\n", data, ha->fwwait);
                 }
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        /* Get fm-capable property */
+        ha->fm_capabilities = DDI_FM_NOT_CAPABLE;
+        if ((data = ql_get_prop(ha, "fm-capable")) != 0xffffffff) {
+                if (data == 0) {
+                        ha->fm_capabilities = DDI_FM_NOT_CAPABLE;
+                } else if (data > 0xf) {
+                        ha->fm_capabilities = 0xf;
+
+                } else {
+                        ha->fm_capabilities = (int)(data);
+                }
+        } else {
+                ha->fm_capabilities = (int)(DDI_FM_EREPORT_CAPABLE
+                    | DDI_FM_ERRCB_CAPABLE);
+        }
+
+        if ((data = ql_get_prop(ha, "msix-vectors")) == 0xffffffff) {
+                ha->mq_msix_vectors = 0;
+        } else if (data < 256) {
+                ha->mq_msix_vectors = (uint8_t)data;
+        } else {
+                EL(ha, "invalid parameter value for 'msix-vectors': "
+                    "%d; using value of %d\n", data, 0);
+                ha->mq_msix_vectors = 0;
+        }
+
+        /* Get number of completion threads. */
+        if ((data = ql_get_prop(ha, "completion-threads")) == 0xffffffff) {
+                ha->completion_thds = 4;
+        } else if (data < 256 && data >= 1) {
+                ha->completion_thds = (uint8_t)data;
+        } else {
+                EL(ha, "invalid parameter value for 'completion-threads':"
+                    " %d; using default value of %d", data, 4);
+                ha->completion_thds = 4;
+        }
+
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_24xx_properties
  *      Copies driver properties to NVRAM or adapter structure.
@@ -1774,98 +1845,98 @@
  *      completely from administrators. Knowledgeable folks can
  *      override the default values using /etc/system.
  *
  * Input:
  *      ha:     adapter state pointer.
- *      nv:     NVRAM structure pointer.
+ *      icb:    Init control block structure pointer.
  *
  * Context:
  *      Kernel context.
  */
 static void
-ql_24xx_properties(ql_adapter_state_t *ha, nvram_24xx_t *nv)
+ql_24xx_properties(ql_adapter_state_t *ha, ql_init_24xx_cb_t *icb)
 {
         uint32_t        data;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         /* Get frame size */
         if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
                 data = 2048;
         }
         if (data == 512 || data == 1024 || data == 2048 || data == 2112) {
-                nv->max_frame_length[0] = LSB(data);
-                nv->max_frame_length[1] = MSB(data);
+                icb->max_frame_length[0] = LSB(data);
+                icb->max_frame_length[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'max-frame-length': %d;"
                     " using nvram default of %d\n", data, CHAR_TO_SHORT(
-                    nv->max_frame_length[0], nv->max_frame_length[1]));
+                    icb->max_frame_length[0], icb->max_frame_length[1]));
         }
 
         /* Get execution throttle. */
         if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
                 data = 32;
         }
         if (data != 0 && data < 65536) {
-                nv->execution_throttle[0] = LSB(data);
-                nv->execution_throttle[1] = MSB(data);
+                icb->execution_throttle[0] = LSB(data);
+                icb->execution_throttle[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'execution-throttle':"
                     " %d; using nvram default of %d\n", data, CHAR_TO_SHORT(
-                    nv->execution_throttle[0], nv->execution_throttle[1]));
+                    icb->execution_throttle[0], icb->execution_throttle[1]));
         }
 
         /* Get Login timeout. */
         if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
                 data = 3;
         }
         if (data < 65536) {
-                nv->login_timeout[0] = LSB(data);
-                nv->login_timeout[1] = MSB(data);
+                icb->login_timeout[0] = LSB(data);
+                icb->login_timeout[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'login-timeout': %d; "
                     "using nvram value of %d\n", data, CHAR_TO_SHORT(
-                    nv->login_timeout[0], nv->login_timeout[1]));
+                    icb->login_timeout[0], icb->login_timeout[1]));
         }
 
         /* Get retry count. */
         if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
                 data = 4;
         }
         if (data < 65536) {
-                nv->login_retry_count[0] = LSB(data);
-                nv->login_retry_count[1] = MSB(data);
+                icb->login_retry_count[0] = LSB(data);
+                icb->login_retry_count[1] = MSB(data);
         } else {
                 EL(ha, "invalid parameter value for 'login-retry-count': "
                     "%d; using nvram value of %d\n", data, CHAR_TO_SHORT(
-                    nv->login_retry_count[0], nv->login_retry_count[1]));
+                    icb->login_retry_count[0], icb->login_retry_count[1]));
         }
 
         /* Get adapter hard loop ID enable. */
         data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
         if (data == 0) {
-                nv->firmware_options_1[0] =
-                    (uint8_t)(nv->firmware_options_1[0] & ~BIT_0);
+                icb->firmware_options_1[0] =
+                    (uint8_t)(icb->firmware_options_1[0] & ~BIT_0);
         } else if (data == 1) {
-                nv->firmware_options_1[0] =
-                    (uint8_t)(nv->firmware_options_1[0] | BIT_0);
+                icb->firmware_options_1[0] =
+                    (uint8_t)(icb->firmware_options_1[0] | BIT_0);
         } else if (data != 0xffffffff) {
                 EL(ha, "invalid parameter value for "
                     "'enable-adapter-hard-loop-ID': %d; using nvram value "
                     "of %d\n", data,
-                    nv->firmware_options_1[0] & BIT_0 ? 1 : 0);
+                    icb->firmware_options_1[0] & BIT_0 ? 1 : 0);
         }
 
         /* Get adapter hard loop ID. */
         data =  ql_get_prop(ha, "adapter-hard-loop-ID");
         if (data < 126) {
-                nv->hard_address[0] = LSB(data);
-                nv->hard_address[1] = MSB(data);
+                icb->hard_address[0] = LSB(data);
+                icb->hard_address[1] = MSB(data);
         } else if (data != 0xffffffff) {
                 EL(ha, "invalid parameter value for 'adapter-hard-loop-ID':"
                     " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
-                    nv->hard_address[0], nv->hard_address[1]));
+                    icb->hard_address[0], icb->hard_address[1]));
         }
 
         /* Get LIP reset. */
         if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
             0xffffffff) {
@@ -1885,91 +1956,105 @@
         if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
             0xffffffff) {
                 data = 1;
         }
         if (data == 0) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
+                ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN;
         } else if (data == 1) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
+                ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN;
         } else {
                 EL(ha, "invalid parameter value for "
                     "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
-                    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
+                    "value of %d\n", data,
+                    ha->cfg_flags & CFG_ENABLE_FULL_LIP_LOGIN ? 1 : 0);
         }
 
         /* Get target reset. */
         if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
             0xffffffff) {
                 data = 0;
         }
         if (data == 0) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
+                ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET;
         } else if (data == 1) {
-                nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
+                ha->cfg_flags |= CFG_ENABLE_TARGET_RESET;
         } else {
                 EL(ha, "invalid parameter value for "
                     "'enable-target-reset-on-bus-reset': %d; using nvram "
-                    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
+                    "value of %d", data,
+                    ha->cfg_flags & CFG_ENABLE_TARGET_RESET ? 1 : 0);
         }
 
         /* Get reset delay. */
         if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
                 data = 5;
         }
         if (data != 0 && data < 256) {
-                nv->reset_delay = (uint8_t)data;
+                ha->loop_reset_delay = (uint8_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'reset-delay': %d; "
-                    "using nvram value of %d", data, nv->reset_delay);
+                    "using nvram value of %d", data, ha->loop_reset_delay);
         }
 
         /* Get port down retry count. */
         if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
                 data = 8;
         }
         if (data < 256) {
-                nv->port_down_retry_count[0] = LSB(data);
-                nv->port_down_retry_count[1] = MSB(data);
+                ha->port_down_retry_count = (uint16_t)data;
         } else {
                 EL(ha, "invalid parameter value for 'port-down-retry-count':"
-                    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
-                    nv->port_down_retry_count[0],
-                    nv->port_down_retry_count[1]));
+                    " %d; using nvram value of %d\n", data,
+                    ha->port_down_retry_count);
         }
 
-        if (!(CFG_IST(ha, CFG_CTRL_8081))) {
+        if (!(CFG_IST(ha, CFG_FCOE_SUPPORT))) {
+                uint32_t        conn;
+
                 /* Get connection mode setting. */
-                if ((data = ql_get_prop(ha, "connection-options")) ==
+                if ((conn = ql_get_prop(ha, "connection-options")) ==
                     0xffffffff) {
-                        data = 2;
+                        conn = 2;
                 }
-                if (data <= 2) {
-                        nv->firmware_options_2[0] = (uint8_t)
-                            (nv->firmware_options_2[0] &
+                if (conn <= 2) {
+                        icb->firmware_options_2[0] = (uint8_t)
+                            (icb->firmware_options_2[0] &
                             ~(BIT_6 | BIT_5 | BIT_4));
-                        nv->firmware_options_2[0] = (uint8_t)
-                            (nv->firmware_options_2[0] | (uint8_t)(data << 4));
+                        icb->firmware_options_2[0] = (uint8_t)
+                            (icb->firmware_options_2[0] | (uint8_t)(conn << 4));
                 } else {
                         EL(ha, "invalid parameter value for 'connection-"
-                            "options': %d; using nvram value of %d\n", data,
-                            (nv->firmware_options_2[0] >> 4) & 0x3);
+                            "options': %d; using nvram value of %d\n", conn,
+                            (icb->firmware_options_2[0] >> 4) & 0x3);
                 }
+                conn = icb->firmware_options_2[0] >> 4 & 0x3;
+                if (conn == 0 && ha->max_vports > 125) {
+                        ha->max_vports = 125;
+                }
 
                 /* Get data rate setting. */
                 if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
                         data = 2;
                 }
-                if ((CFG_IST(ha, CFG_CTRL_2422) && data < 4) ||
-                    (CFG_IST(ha, CFG_CTRL_258081) && data < 5)) {
-                        nv->firmware_options_3[1] = (uint8_t)
-                            (nv->firmware_options_3[1] & 0x1f);
-                        nv->firmware_options_3[1] = (uint8_t)
-                            (nv->firmware_options_3[1] | (uint8_t)(data << 5));
+                if ((CFG_IST(ha, CFG_CTRL_24XX) && data < 4) ||
+                    (CFG_IST(ha, CFG_CTRL_25XX) && data < 5) ||
+                    (CFG_IST(ha, CFG_CTRL_2783) && data < 6)) {
+                        if (CFG_IST(ha, CFG_CTRL_2783) && data == 5 &&
+                            conn == 0) {
+                                EL(ha, "invalid parameter value for 'fc-data-"
+                                    "rate': %d; using nvram value of %d\n",
+                                    data, 2);
+                                data = 2;
+                        }
+                        icb->firmware_options_3[1] = (uint8_t)
+                            (icb->firmware_options_3[1] & 0x1f);
+                        icb->firmware_options_3[1] = (uint8_t)
+                            (icb->firmware_options_3[1] | (uint8_t)(data << 5));
                 } else {
                         EL(ha, "invalid parameter value for 'fc-data-rate': "
                             "%d; using nvram value of %d\n", data,
-                            (nv->firmware_options_3[1] >> 5) & 0x7);
+                            (icb->firmware_options_3[1] >> 5) & 0x7);
                 }
         }
 
         /* Get IP FW container count. */
         ha->ip_init_ctrl_blk.cb24.cc[0] = LSB(ql_ip_buffer_count);
@@ -2014,11 +2099,11 @@
 
         ql_common_properties(ha);
 
         ADAPTER_STATE_UNLOCK(ha);
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 }
 
 /*
  * ql_get_prop
  *      Get property value from configuration file.
@@ -2040,11 +2125,11 @@
         uint32_t        data = 0xffffffff;
 
         /*
          * Look for a adapter instance NPIV (virtual port) specific parameter
          */
-        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 (void) sprintf(buf, "hba%d-vp%d-%s", ha->instance,
                     ha->vp_index, string);
                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
                 data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
                     buf, (int)0xffffffff);
@@ -2093,31 +2178,42 @@
         uint32_t        byte_count;
         uint32_t        fw_size, *lptr;
         caddr_t         bufp;
         uint16_t        risc_address = (uint16_t)ha->risc_fw[0].addr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         /* Test for firmware running. */
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
-                if (ql_8021_idc_handler(ha) != NX_DEV_READY) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                if ((rval = ql_8021_fw_chk(ha)) == QL_SUCCESS) {
+                        rval = ql_start_firmware(ha);
+                }
+        } else if (CFG_IST(ha, CFG_CTRL_278083)) {
+                ha->dev_state = NX_DEV_READY;
+                if (ha->rom_status == MBS_ROM_FW_RUNNING) {
+                        EL(ha, "ISP ROM Status = MBS_ROM_FW_RUNNING\n");
+                        rval = QL_SUCCESS;
+                } else if (ha->rom_status == MBS_ROM_IDLE) {
+                        EL(ha, "ISP ROM Status = MBS_ROM_IDLE\n");
                         rval = QL_FUNCTION_FAILED;
                 } else {
-                        rval = ql_start_firmware(ha);
+                        EL(ha, "ISP ROM Status, mbx0=%xh\n", ha->rom_status);
+                        rval = QL_FUNCTION_FAILED;
                 }
         } else if (CFG_IST(ha, CFG_DISABLE_RISC_CODE_LOAD)) {
+                ha->dev_state = NX_DEV_READY;
                 if (ha->risc_code != NULL) {
                         kmem_free(ha->risc_code, ha->risc_code_size);
                         ha->risc_code = NULL;
                         ha->risc_code_size = 0;
                 }
 
                 /* Get RISC code length. */
-                rval = ql_rd_risc_ram(ha, risc_address + 3, ha->request_dvma,
-                    1);
+                rval = ql_rd_risc_ram(ha, risc_address + 3,
+                    ha->req_q[0]->req_ring.cookie.dmac_laddress, 1);
                 if (rval == QL_SUCCESS) {
-                        lptr = (uint32_t *)ha->request_ring_bp;
+                        lptr = (uint32_t *)ha->req_q[0]->req_ring.bp;
                         fw_size = *lptr << 1;
 
                         if ((bufp = kmem_alloc(fw_size, KM_SLEEP)) != NULL) {
                                 ha->risc_code_size = fw_size;
                                 ha->risc_code = bufp;
@@ -2134,27 +2230,28 @@
 
                                         word_count =
                                             (uint16_t)(byte_count >> 1);
 
                                         rval = ql_rd_risc_ram(ha, risc_address,
-                                            ha->request_dvma, word_count);
+                                            ha->req_q[0]->req_ring.cookie.
+                                            dmac_laddress, word_count);
                                         if (rval != QL_SUCCESS) {
                                                 kmem_free(ha->risc_code,
                                                     ha->risc_code_size);
                                                 ha->risc_code = NULL;
                                                 ha->risc_code_size = 0;
                                                 break;
                                         }
 
                                         (void) ddi_dma_sync(
-                                            ha->hba_buf.dma_handle,
-                                            REQUEST_Q_BUFFER_OFFSET,
-                                            byte_count,
+                                            ha->req_q[0]->req_ring.dma_handle,
+                                            0, byte_count,
                                             DDI_DMA_SYNC_FORKERNEL);
-                                        ddi_rep_get16(ha->hba_buf.acc_handle,
-                                            (uint16_t *)bufp,
-                                            (uint16_t *)ha->request_ring_bp,
+                                        ddi_rep_get16(
+                                            ha->req_q[0]->req_ring.acc_handle,
+                                            (uint16_t *)bufp, (uint16_t *)
+                                            ha->req_q[0]->req_ring.bp,
                                             word_count, DDI_DEV_AUTOINCR);
 
                                         risc_address += word_count;
                                         fw_size -= byte_count;
                                         bufp    += byte_count;
@@ -2161,140 +2258,24 @@
                                 } while (fw_size != 0);
                         }
                         rval = QL_FUNCTION_FAILED;
                 }
         } else {
+                ha->dev_state = NX_DEV_READY;
                 rval = QL_FUNCTION_FAILED;
         }
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "Load RISC code\n");
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
- * Chip diagnostics
- *      Test chip for proper operation.
- *
- * Input:
- *      ha = adapter state pointer.
- *
- * Returns:
- *      ql local function return status code.
- *
- * Context:
- *      Kernel context.
- */
-static int
-ql_chip_diag(ql_adapter_state_t *ha)
-{
-        ql_mbx_data_t   mr;
-        int             rval;
-        int32_t         retries = 4;
-        uint16_t        id;
-
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
-
-        do {
-                /* Reset ISP chip. */
-                TASK_DAEMON_LOCK(ha);
-                ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
-                TASK_DAEMON_UNLOCK(ha);
-
-                /* For ISP2200A reduce firmware load size. */
-                if (CFG_IST(ha, CFG_CTRL_2200) &&
-                    RD16_IO_REG(ha, mailbox_out[7]) == 4) {
-                        ha->fw_transfer_size = 128;
-                } else {
-                        ha->fw_transfer_size = REQUEST_QUEUE_SIZE;
-                }
-
-                rval = QL_SUCCESS;
-                if (!(CFG_IST(ha, CFG_CTRL_8021))) {
-                        ql_reset_chip(ha);
-
-                        /* Check product ID of chip */
-                        mr.mb[1] = RD16_IO_REG(ha, mailbox_out[1]);
-                        mr.mb[2] = RD16_IO_REG(ha, mailbox_out[2]);
-                        mr.mb[3] = RD16_IO_REG(ha, mailbox_out[3]);
-
-                        if (ha->device_id == 0x5432 ||
-                            ha->device_id == 0x8432) {
-                                id = 0x2432;
-                        } else if (ha->device_id == 0x5422 ||
-                            ha->device_id == 0x8422) {
-                                id = 0x2422;
-                        } else {
-                                id = ha->device_id;
-                        }
-
-                        if (mr.mb[1] == PROD_ID_1 &&
-                            (mr.mb[2] == PROD_ID_2 || mr.mb[2] == PROD_ID_2a) &&
-                            (mr.mb[3] == PROD_ID_3 || mr.mb[3] == id)) {
-                                ha->adapter_stats->revlvl.isp2200 =
-                                    RD16_IO_REG(ha, mailbox_out[4]);
-                                ha->adapter_stats->revlvl.risc =
-                                    RD16_IO_REG(ha, mailbox_out[5]);
-                                ha->adapter_stats->revlvl.frmbfr =
-                                    RD16_IO_REG(ha, mailbox_out[6]);
-                                ha->adapter_stats->revlvl.riscrom =
-                                    RD16_IO_REG(ha, mailbox_out[7]);
-                        } else {
-                                cmn_err(CE_WARN, "%s(%d) - prod id failed!, "
-                                    "mb1=%xh, mb2=%xh, mb3=%xh", QL_NAME,
-                                    ha->instance, mr.mb[1], mr.mb[2], mr.mb[3]);
-                                rval = QL_FUNCTION_FAILED;
-                        }
-                } else if (!(ha->task_daemon_flags & FIRMWARE_LOADED)) {
-                        break;
-                }
-
-                if (rval == QL_SUCCESS) {
-                        /* Wrap Incoming Mailboxes Test. */
-                        mr.mb[1] = 0xAAAA;
-                        mr.mb[2] = 0x5555;
-                        mr.mb[3] = 0xAA55;
-                        mr.mb[4] = 0x55AA;
-                        mr.mb[5] = 0xA5A5;
-                        mr.mb[6] = 0x5A5A;
-                        mr.mb[7] = 0x2525;
-                        rval = ql_mbx_wrap_test(ha, &mr);
-                        if (rval == QL_SUCCESS) {
-                                if (mr.mb[1] != 0xAAAA ||
-                                    mr.mb[2] != 0x5555 ||
-                                    mr.mb[3] != 0xAA55 ||
-                                    mr.mb[4] != 0x55AA ||
-                                    mr.mb[5] != 0xA5A5 ||
-                                    mr.mb[6] != 0x5A5A ||
-                                    mr.mb[7] != 0x2525) {
-                                        rval = QL_FUNCTION_FAILED;
-                                        (void) ql_flash_errlog(ha,
-                                            FLASH_ERRLOG_ISP_ERR, 0,
-                                            RD16_IO_REG(ha, hccr),
-                                            RD16_IO_REG(ha, istatus));
-                                }
-                        } else {
-                                cmn_err(CE_WARN, "%s(%d) - reg test failed="
-                                    "%xh!", QL_NAME, ha->instance, rval);
-                        }
-                }
-        } while ((retries-- != 0) && (rval != QL_SUCCESS));
-
-        if (rval != QL_SUCCESS) {
-                EL(ha, "failed, rval = %xh\n", rval);
-        } else {
-                /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
-        }
-        return (rval);
-}
-
-/*
  * ql_load_isp_firmware
  *      Load and start RISC firmware.
  *      Uses request ring for DMA buffer.
  *
  * Input:
@@ -2309,67 +2290,81 @@
 int
 ql_load_isp_firmware(ql_adapter_state_t *vha)
 {
         caddr_t                 risc_code_address;
         uint32_t                risc_address, risc_code_size;
-        int                     rval;
+        int                     rval = QL_FUNCTION_FAILED;
         uint32_t                word_count, cnt;
         size_t                  byte_count;
         ql_adapter_state_t      *ha = vha->pha;
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
-                rval = ql_8021_load_risc(ha);
+        QL_PRINT_10(ha, "started\n");
+
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
+                rval = ql_8021_reset_fw(ha) == NX_DEV_READY ?
+                    QL_SUCCESS : QL_FUNCTION_FAILED;
         } else {
                 if (CFG_IST(ha, CFG_CTRL_81XX)) {
                         ql_mps_reset(ha);
                 }
 
                 if (CFG_IST(ha, CFG_LOAD_FLASH_FW)) {
+                        QL_PRINT_10(ha, "CFG_LOAD_FLASH_FW exit\n");
                         return (ql_load_flash_fw(ha));
                 }
 
-                QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+                if (CFG_IST(ha, CFG_CTRL_27XX)) {
+                        (void) ql_2700_get_module_dmp_template(ha);
+                }
 
                 /* Load firmware segments */
                 for (cnt = 0; cnt < MAX_RISC_CODE_SEGMENTS &&
                     ha->risc_fw[cnt].code != NULL; cnt++) {
 
                         risc_code_address = ha->risc_fw[cnt].code;
                         risc_address = ha->risc_fw[cnt].addr;
+                        if ((risc_address = ha->risc_fw[cnt].addr) == 0) {
+                                continue;
+                        }
                         risc_code_size = ha->risc_fw[cnt].length;
 
                         while (risc_code_size) {
-                                if (CFG_IST(ha, CFG_CTRL_242581)) {
+                                if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                                         word_count = ha->fw_transfer_size >> 2;
                                         if (word_count > risc_code_size) {
                                                 word_count = risc_code_size;
                                         }
                                         byte_count = word_count << 2;
 
-                                        ddi_rep_put32(ha->hba_buf.acc_handle,
+                                        ddi_rep_put32(
+                                            ha->req_q[0]->req_ring.acc_handle,
                                             (uint32_t *)risc_code_address,
-                                            (uint32_t *)ha->request_ring_bp,
+                                            (uint32_t *)
+                                            ha->req_q[0]->req_ring.bp,
                                             word_count, DDI_DEV_AUTOINCR);
                                 } else {
                                         word_count = ha->fw_transfer_size >> 1;
                                         if (word_count > risc_code_size) {
                                                 word_count = risc_code_size;
                                         }
                                         byte_count = word_count << 1;
 
-                                        ddi_rep_put16(ha->hba_buf.acc_handle,
+                                        ddi_rep_put16(
+                                            ha->req_q[0]->req_ring.acc_handle,
                                             (uint16_t *)risc_code_address,
-                                            (uint16_t *)ha->request_ring_bp,
+                                            (uint16_t *)
+                                            ha->req_q[0]->req_ring.bp,
                                             word_count, DDI_DEV_AUTOINCR);
                                 }
 
-                                (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                                    REQUEST_Q_BUFFER_OFFSET, byte_count,
-                                    DDI_DMA_SYNC_FORDEV);
+                                (void) ddi_dma_sync(
+                                    ha->req_q[0]->req_ring.dma_handle,
+                                    0, byte_count, DDI_DMA_SYNC_FORDEV);
 
                                 rval = ql_wrt_risc_ram(ha, risc_address,
-                                    ha->request_dvma, word_count);
+                                    ha->req_q[0]->req_ring.cookie.dmac_laddress,
+                                    word_count);
                                 if (rval != QL_SUCCESS) {
                                         EL(ha, "failed, load=%xh\n", rval);
                                         cnt = MAX_RISC_CODE_SEGMENTS;
                                         break;
                                 }
@@ -2378,10 +2373,11 @@
                                 risc_code_size -= word_count;
                                 risc_code_address += byte_count;
                         }
                 }
         }
+        bzero(ha->req_q[0]->req_ring.bp, ha->fw_transfer_size);
 
         /* Start firmware. */
         if (rval == QL_SUCCESS) {
                 rval = ql_start_firmware(ha);
         }
@@ -2388,11 +2384,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
 
         return (rval);
 }
 
@@ -2412,56 +2408,71 @@
         int             rval;
         uint8_t         seg_cnt;
         uint32_t        risc_address, xfer_size, count, *bp, faddr;
         uint32_t        risc_code_size = 0;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
+        if (CFG_IST(ha, CFG_CTRL_278083)) {
+                if ((rval = ql_load_flash_image(ha)) != QL_SUCCESS) {
+                        EL(ha, "load_flash_image status=%xh\n", rval);
+                } else if (CFG_IST(ha, CFG_CTRL_27XX) &&
+                    (rval = ql_2700_get_flash_dmp_template(ha)) !=
+                    QL_SUCCESS) {
+                        EL(ha, "get_flash_dmp_template status=%xh\n", rval);
+                }
+        } else {
         faddr = ha->flash_data_addr | ha->flash_fw_addr;
 
         for (seg_cnt = 0; seg_cnt < 2; seg_cnt++) {
                 xfer_size = ha->fw_transfer_size >> 2;
                 do {
                         GLOBAL_HW_LOCK();
 
                         /* Read data from flash. */
-                        bp = (uint32_t *)ha->request_ring_bp;
+                                bp = (uint32_t *)ha->req_q[0]->req_ring.bp;
                         for (count = 0; count < xfer_size; count++) {
-                                rval = ql_24xx_read_flash(ha, faddr++, bp);
+                                        rval = ql_24xx_read_flash(ha, faddr++,
+                                            bp);
                                 if (rval != QL_SUCCESS) {
                                         break;
                                 }
                                 ql_chg_endian((uint8_t *)bp++, 4);
                         }
 
                         GLOBAL_HW_UNLOCK();
 
                         if (rval != QL_SUCCESS) {
-                                EL(ha, "24xx_read_flash failed=%xh\n", rval);
+                                        EL(ha, "24xx_read_flash failed=%xh\n",
+                                            rval);
                                 break;
                         }
 
                         if (risc_code_size == 0) {
-                                bp = (uint32_t *)ha->request_ring_bp;
+                                        bp = (uint32_t *)
+                                            ha->req_q[0]->req_ring.bp;
                                 risc_address = bp[2];
                                 risc_code_size = bp[3];
-                                ha->risc_fw[seg_cnt].addr = risc_address;
+                                        ha->risc_fw[seg_cnt].addr =
+                                            risc_address;
                         }
 
                         if (risc_code_size < xfer_size) {
                                 faddr -= xfer_size - risc_code_size;
                                 xfer_size = risc_code_size;
                         }
 
-                        (void) ddi_dma_sync(ha->hba_buf.dma_handle,
-                            REQUEST_Q_BUFFER_OFFSET, xfer_size << 2,
-                            DDI_DMA_SYNC_FORDEV);
+                                (void) ddi_dma_sync(
+                                    ha->req_q[0]->req_ring.dma_handle,
+                                    0, xfer_size << 2, DDI_DMA_SYNC_FORDEV);
 
                         rval = ql_wrt_risc_ram(ha, risc_address,
-                            ha->request_dvma, xfer_size);
+                                    ha->req_q[0]->req_ring.cookie.dmac_laddress,
+                                    xfer_size);
                         if (rval != QL_SUCCESS) {
-                                EL(ha, "ql_wrt_risc_ram failed=%xh\n", rval);
+                                        EL(ha, "ql_wrt_risc_ram failed=%xh\n",
+                                            rval);
                                 break;
                         }
 
                         risc_address += xfer_size;
                         risc_code_size -= xfer_size;
@@ -2469,10 +2480,11 @@
 
                 if (rval != QL_SUCCESS) {
                         break;
                 }
         }
+        }
 
         /* Start firmware. */
         if (rval == QL_SUCCESS) {
                 rval = ql_start_firmware(ha);
         }
@@ -2479,11 +2491,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -2502,16 +2514,18 @@
 int
 ql_start_firmware(ql_adapter_state_t *vha)
 {
         int                     rval, rval2;
         uint32_t                data;
-        ql_mbx_data_t           mr;
+        ql_mbx_data_t           mr = {0};
         ql_adapter_state_t      *ha = vha->pha;
+        ql_init_24xx_cb_t       *icb =
+            (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 /* Save firmware version. */
                 rval = ql_get_fw_version(ha, &mr, MAILBOX_TOV);
                 ha->fw_major_version = mr.mb[1];
                 ha->fw_minor_version = mr.mb[2];
                 ha->fw_subminor_version = mr.mb[3];
@@ -2524,36 +2538,55 @@
                 /* Save firmware version. */
                 (void) ql_get_fw_version(ha, &mr, MAILBOX_TOV);
                 ha->fw_major_version = mr.mb[1];
                 ha->fw_minor_version = mr.mb[2];
                 ha->fw_subminor_version = mr.mb[3];
-                ha->fw_ext_memory_size = ((SHORT_TO_LONG(mr.mb[4], mr.mb[5]) -
+                ha->fw_ext_memory_end = SHORT_TO_LONG(mr.mb[4], mr.mb[5]);
+                ha->fw_ext_memory_size = ((ha->fw_ext_memory_end -
                     0x100000) + 1) * 4;
+                if (CFG_IST(ha, CFG_CTRL_278083)) {
+                        ha->fw_attributes = SHORT_TO_LONG(mr.mb[6], mr.mb[15]);
+                        ha->phy_fw_major_version = LSB(mr.mb[13]);
+                        ha->phy_fw_minor_version = MSB(mr.mb[14]);
+                        ha->phy_fw_subminor_version = LSB(mr.mb[14]);
+                        ha->fw_ext_attributes = SHORT_TO_LONG(mr.mb[16],
+                            mr.mb[17]);
+                } else {
                 ha->fw_attributes = mr.mb[6];
-
-                if (CFG_IST(ha, CFG_CTRL_81XX)) {
                         ha->phy_fw_major_version = LSB(mr.mb[8]);
                         ha->phy_fw_minor_version = MSB(mr.mb[9]);
                         ha->phy_fw_subminor_version = LSB(mr.mb[9]);
+                        ha->mpi_capability_list =
+                            SHORT_TO_LONG(mr.mb[13], mr.mb[12]);
+                }
                         ha->mpi_fw_major_version = LSB(mr.mb[10]);
                         ha->mpi_fw_minor_version = MSB(mr.mb[11]);
                         ha->mpi_fw_subminor_version = LSB(mr.mb[11]);
-                        ha->mpi_capability_list = SHORT_TO_LONG(mr.mb[13],
-                            mr.mb[12]);
+                if (CFG_IST(ha, CFG_CTRL_27XX)) {
+                        ha->fw_shared_ram_start =
+                            SHORT_TO_LONG(mr.mb[18], mr.mb[19]);
+                        ha->fw_shared_ram_end =
+                            SHORT_TO_LONG(mr.mb[20], mr.mb[21]);
+                        ha->fw_ddr_ram_start =
+                            SHORT_TO_LONG(mr.mb[22], mr.mb[23]);
+                        ha->fw_ddr_ram_end =
+                            SHORT_TO_LONG(mr.mb[24], mr.mb[25]);
+                }
+                if (CFG_IST(ha, CFG_FLASH_ACC_SUPPORT)) {
                         if ((rval2 = ql_flash_access(ha, FAC_GET_SECTOR_SIZE,
                             0, 0, &data)) == QL_SUCCESS) {
                                 ha->xioctl->fdesc.block_size = data << 2;
-                                QL_PRINT_10(CE_CONT, "(%d): fdesc.block_size="
-                                    "%xh\n", ha->instance,
+                                QL_PRINT_10(ha, "fdesc.block_size="
+                                    "%xh\n",
                                     ha->xioctl->fdesc.block_size);
                         } else {
                                 EL(ha, "flash_access status=%xh\n", rval2);
                         }
                 }
 
                 /* Set Serdes Transmit Parameters. */
-                if (CFG_IST(ha, CFG_CTRL_2422) && ha->serdes_param[0] & BIT_0) {
+                if (CFG_IST(ha, CFG_CTRL_24XX) && ha->serdes_param[0] & BIT_0) {
                         mr.mb[1] = ha->serdes_param[0];
                         mr.mb[2] = ha->serdes_param[1];
                         mr.mb[3] = ha->serdes_param[2];
                         mr.mb[4] = ha->serdes_param[3];
                         (void) ql_serdes_param(ha, &mr);
@@ -2565,16 +2598,59 @@
                         mr.mb[2] = (uint16_t)
                             (mr.mb[2] | FO2_FCOE_512_MAX_MEM_WR_BURST);
                         (void) ql_set_firmware_option(ha, &mr);
                 }
         }
+
+        if (ha->flags & MULTI_QUEUE) {
+                QL_PRINT_10(ha, "MULTI_QUEUE\n");
+                icb->msi_x_vector[0] = LSB(ha->rsp_queues[0]->msi_x_vector);
+                icb->msi_x_vector[1] = MSB(ha->rsp_queues[0]->msi_x_vector);
+                if (ha->iflags & IFLG_INTR_MSIX &&
+                    CFG_IST(ha, CFG_NO_INTR_HSHAKE_SUP)) {
+                        QL_PRINT_10(ha, "NO_INTR_HANDSHAKE\n");
+                        ADAPTER_STATE_LOCK(ha);
+                        ha->flags |= NO_INTR_HANDSHAKE;
+                        ADAPTER_STATE_UNLOCK(ha);
+                        icb->firmware_options_2[2] = (uint8_t)
+                            (icb->firmware_options_2[2] & ~(BIT_6 | BIT_5));
+                        icb->firmware_options_2[2] = (uint8_t)
+                            (icb->firmware_options_2[2] | BIT_7);
+                } else {
+                        icb->firmware_options_2[2] = (uint8_t)
+                            (icb->firmware_options_2[2] & ~BIT_5);
+                        icb->firmware_options_2[2] = (uint8_t)
+                            (icb->firmware_options_2[2] | BIT_7 | BIT_6);
+                }
+        } else {
+                icb->firmware_options_2[2] = (uint8_t)
+                    (icb->firmware_options_2[2] & ~(BIT_7 | BIT_5));
+                icb->firmware_options_2[2] = (uint8_t)
+                    (icb->firmware_options_2[2] | BIT_6);
+        }
+        icb->firmware_options_2[3] = (uint8_t)
+            (icb->firmware_options_2[3] & ~(BIT_1 | BIT_0));
+
+        /* Set fw execution throttle. */
+        if (CFG_IST(ha, CFG_CTRL_22XX) ||
+            ql_get_resource_cnts(ha, &mr) != QL_SUCCESS) {
+                icb->execution_throttle[0] = 0xff;
+                icb->execution_throttle[1] = 0xff;
+        } else {
+                icb->execution_throttle[0] = LSB(mr.mb[6]);
+                icb->execution_throttle[1] = MSB(mr.mb[6]);
+        }
+        EL(ha, "icb->execution_throttle %d\n",
+            CHAR_TO_SHORT(icb->execution_throttle[0],
+            icb->execution_throttle[1]));
+
         if (rval != QL_SUCCESS) {
                 ha->task_daemon_flags &= ~FIRMWARE_LOADED;
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 ha->task_daemon_flags |= FIRMWARE_LOADED;
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -2591,19 +2667,19 @@
  *      Kernel context.
  */
 int
 ql_set_cache_line(ql_adapter_state_t *ha)
 {
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Set the cache line. */
         if (CFG_IST(ha->pha, CFG_SET_CACHE_LINE_SIZE_1)) {
                 /* Set cache line register. */
                 ql_pci_config_put8(ha->pha, PCI_CONF_CACHE_LINESZ, 1);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_3(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*
@@ -2613,11 +2689,12 @@
  *      Beginning of response ring has initialization control block
  *      already built by nvram config routine.
  *
  * Input:
  *      ha = adapter state pointer.
- *      ha->hba_buf = request and response rings
+ *      ha->req_q =             request rings
+ *      ha->rsp_queues =        response rings
  *      ha->init_ctrl_blk = initialization control block
  *
  * Returns:
  *      ql local function return status code.
  *
@@ -2630,55 +2707,58 @@
         int                     rval, rval2;
         uint16_t                index;
         ql_mbx_data_t           mr;
         ql_adapter_state_t      *ha = vha2->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
         /* Clear outstanding commands array. */
-        for (index = 0; index < MAX_OUTSTANDING_COMMANDS; index++) {
+        for (index = 0; index < ha->osc_max_cnt; index++) {
                 ha->outstanding_cmds[index] = NULL;
         }
         ha->osc_index = 1;
 
         ha->pending_cmds.first = NULL;
         ha->pending_cmds.last = NULL;
 
         /* Initialize firmware. */
-        ha->request_ring_ptr = ha->request_ring_bp;
-        ha->req_ring_index = 0;
-        ha->req_q_cnt = REQUEST_ENTRY_CNT - 1;
-        ha->response_ring_ptr = ha->response_ring_bp;
-        ha->rsp_ring_index = 0;
+        ha->req_q[0]->req_ring_ptr = ha->req_q[0]->req_ring.bp;
+        ha->req_q[0]->req_ring_index = 0;
+        ha->req_q[0]->req_q_cnt = REQUEST_ENTRY_CNT - 1;
+        ha->rsp_queues[0]->rsp_ring_ptr = ha->rsp_queues[0]->rsp_ring.bp;
+        ha->rsp_queues[0]->rsp_ring_index = 0;
 
         if (ha->flags & VP_ENABLED) {
                 ql_adapter_state_t      *vha;
-                uint16_t                cnt;
-                uint32_t                max_vports;
                 ql_init_24xx_cb_t       *icb = &ha->init_ctrl_blk.cb24;
 
-                max_vports = (CFG_IST(ha, CFG_CTRL_2422) ?
-                    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS);
                 bzero(icb->vp_count,
                     ((uintptr_t)icb + sizeof (ql_init_24xx_cb_t)) -
                     (uintptr_t)icb->vp_count);
-                icb->vp_count[0] = (uint8_t)max_vports;
+                icb->vp_count[0] = ha->max_vports - 1;
 
                 /* Allow connection option 2. */
                 icb->global_vp_option[0] = BIT_1;
 
-                for (cnt = 0, vha = ha->vp_next; cnt < max_vports &&
-                    vha != NULL; vha = vha->vp_next, cnt++) {
+                /* Setup default options for all ports. */
+                for (index = 0; index < ha->max_vports; index++) {
+                        icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
+                            VPO_INITIATOR_MODE_ENABLED;
+                }
+                /* Setup enabled ports. */
+                for (vha = ha->vp_next; vha != NULL; vha = vha->vp_next) {
+                        if (vha->vp_index == 0 ||
+                            vha->vp_index >= ha->max_vports) {
+                                continue;
+                        }
 
                         index = (uint8_t)(vha->vp_index - 1);
                         bcopy(vha->loginparams.node_ww_name.raw_wwn,
                             icb->vpc[index].node_name, 8);
                         bcopy(vha->loginparams.nport_ww_name.raw_wwn,
                             icb->vpc[index].port_name, 8);
 
-                        icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
-                            VPO_INITIATOR_MODE_ENABLED;
                         if (vha->flags & VP_ENABLED) {
                                 icb->vpc[index].options = (uint8_t)
                                     (icb->vpc[index].options | VPO_ENABLED);
                         }
                 }
@@ -2692,11 +2772,11 @@
                 } else {
                         break;
                 }
         }
 
-        if (rval == QL_SUCCESS && (CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+        if (rval == QL_SUCCESS && CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
                 /* Tell firmware to enable MBA_PORT_BYPASS_CHANGED event */
                 rval = ql_get_firmware_option(ha, &mr);
                 if (rval == QL_SUCCESS) {
                         mr.mb[1] = (uint16_t)(mr.mb[1] | BIT_9);
                         mr.mb[2] = 0;
@@ -2710,11 +2790,11 @@
                 if ((rval2 = ql_get_dma_mem(ha, &ha->fwfcetracebuf, FWFCESIZE,
                     LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
                         EL(ha, "fcetrace buffer alloc failed: %xh\n", rval2);
                 } else {
                         if ((rval2 = ql_fw_etrace(ha, &ha->fwfcetracebuf,
-                            FTO_FCE_TRACE_ENABLE)) != QL_SUCCESS) {
+                            FTO_FCE_TRACE_ENABLE, NULL)) != QL_SUCCESS) {
                                 EL(ha, "fcetrace enable failed: %xh\n", rval2);
                                 ql_free_phys(ha, &ha->fwfcetracebuf);
                         }
                 }
         }
@@ -2724,11 +2804,11 @@
                 if ((rval2 = ql_get_dma_mem(ha, &ha->fwexttracebuf, FWEXTSIZE,
                     LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
                         EL(ha, "exttrace buffer alloc failed: %xh\n", rval2);
                 } else {
                         if ((rval2 = ql_fw_etrace(ha, &ha->fwexttracebuf,
-                            FTO_EXT_TRACE_ENABLE)) != QL_SUCCESS) {
+                            FTO_EXT_TRACE_ENABLE, NULL)) != QL_SUCCESS) {
                                 EL(ha, "exttrace enable failed: %xh\n", rval2);
                                 ql_free_phys(ha, &ha->fwexttracebuf);
                         }
                 }
         }
@@ -2800,11 +2880,11 @@
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 TASK_DAEMON_LOCK(ha);
                 ha->task_daemon_flags |= FIRMWARE_UP;
                 TASK_DAEMON_UNLOCK(ha);
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -2824,34 +2904,50 @@
  */
 int
 ql_fw_ready(ql_adapter_state_t *ha, uint8_t secs)
 {
         ql_mbx_data_t   mr;
-        clock_t         timer;
+        clock_t         timer, login_wait, wait;
         clock_t         dly = 250000;
         clock_t         sec_delay = MICROSEC / dly;
-        clock_t         wait = secs * sec_delay;
         int             rval = QL_FUNCTION_FAILED;
-        uint16_t        state = 0xffff;
+        uint16_t        state[6] = {0};
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_3(ha, "started\n");
 
-        timer = ha->r_a_tov < secs ? secs : ha->r_a_tov;
-        timer = (timer + 2) * sec_delay;
+        login_wait = ha->r_a_tov * 2 * sec_delay;
+        timer = wait = secs * sec_delay;
+        state[0] = 0xffff;
 
         /* Wait for ISP to finish LIP */
-        while (timer != 0 && wait != 0 &&
-            !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
+        while (login_wait != 0 && wait != 0 &&
+            !(ha->task_daemon_flags & ISP_ABORT_NEEDED) &&
+            !(ha->flags & MPI_RESET_NEEDED)) {
 
                 rval = ql_get_firmware_state(ha, &mr);
                 if (rval == QL_SUCCESS) {
-                        if (ha->task_daemon_flags & (ISP_ABORT_NEEDED |
-                            LOOP_DOWN)) {
-                                wait--;
-                        } else if (mr.mb[1] != FSTATE_READY) {
+                        if (mr.mb[1] != FSTATE_READY) {
+                                if (mr.mb[1] == FSTATE_LOSS_SYNC &&
+                                    mr.mb[4] == FSTATE_MPI_NIC_ERROR &&
+                                    CFG_IST(ha, CFG_FCOE_SUPPORT)) {
+                                        EL(ha, "mpi_nic_error, "
+                                            "isp_abort_needed\n");
+                                        ADAPTER_STATE_LOCK(ha);
+                                        ha->flags |= MPI_RESET_NEEDED;
+                                        ADAPTER_STATE_UNLOCK(ha);
+                                        if (!(ha->task_daemon_flags &
+                                            ABORT_ISP_ACTIVE)) {
+                                                TASK_DAEMON_LOCK(ha);
+                                                ha->task_daemon_flags |=
+                                                    ISP_ABORT_NEEDED;
+                                                TASK_DAEMON_UNLOCK(ha);
+                                        }
+                                }
                                 if (mr.mb[1] != FSTATE_WAIT_LOGIN) {
-                                        wait--;
+                                        timer = --wait;
+                                } else {
+                                        timer = --login_wait;
                                 }
                                 rval = QL_FUNCTION_FAILED;
                         } else {
                                 /* Firmware is ready. Get 2 * R_A_TOV. */
                                 rval = ql_get_timeout_parameters(ha,
@@ -2873,20 +2969,29 @@
                                 } else {
                                         break;
                                 }
                         }
                 } else {
-                        wait--;
+                        break;
                 }
 
-                if (state != mr.mb[1]) {
-                        EL(ha, "mailbox_reg[1] = %xh\n", mr.mb[1]);
-                        state = mr.mb[1];
+                if (state[0] != mr.mb[1] || state[1] != mr.mb[2] ||
+                    state[2] != mr.mb[3] || state[3] != mr.mb[4] ||
+                    state[4] != mr.mb[5] || state[5] != mr.mb[6]) {
+                        EL(ha, "mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, "
+                            "mbx5=%xh, mbx6=%xh\n", mr.mb[1], mr.mb[2],
+                            mr.mb[3], mr.mb[4], mr.mb[5], mr.mb[6]);
+                        state[0] = mr.mb[1];
+                        state[1] = mr.mb[2];
+                        state[2] = mr.mb[3];
+                        state[3] = mr.mb[4];
+                        state[4] = mr.mb[5];
+                        state[5] = mr.mb[6];
                 }
 
                 /* Delay for a tick if waiting. */
-                if (timer-- != 0 && wait != 0) {
+                if (timer != 0) {
                         if (timer % 4 == 0) {
                                 delay(drv_usectohz(dly));
                         } else {
                                 drv_usecwait(dly);
                         }
@@ -2894,14 +2999,21 @@
                         rval = QL_FUNCTION_TIMEOUT;
                 }
         }
 
         if (rval != QL_SUCCESS) {
+                if ((ha->task_daemon_flags & ISP_ABORT_NEEDED ||
+                    ha->flags & MPI_RESET_NEEDED) &&
+                    ha->task_daemon_flags & LOOP_RESYNC_NEEDED) {
+                        TASK_DAEMON_LOCK(ha);
+                        ha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
+                        TASK_DAEMON_UNLOCK(ha);
+                }
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_3(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -2918,19 +3030,21 @@
  *      Kernel context.
  */
 static int
 ql_configure_loop(ql_adapter_state_t *ha)
 {
-        int                     rval;
+        int                     rval = QL_SUCCESS;
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         for (vha = ha; vha != NULL; vha = vha->vp_next) {
                 TASK_DAEMON_LOCK(ha);
                 if (!(vha->task_daemon_flags & LOOP_RESYNC_NEEDED) &&
-                    vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
+                    vha->vp_index != 0 &&
+                    (!(vha->flags & VP_ENABLED) ||
+                    vha->flags & VP_ID_NOT_ACQUIRED)) {
                         TASK_DAEMON_UNLOCK(ha);
                         continue;
                 }
                 vha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
                 TASK_DAEMON_UNLOCK(ha);
@@ -2948,11 +3062,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -2965,33 +3079,79 @@
  * Returns:
  *      ql local function return status code.
  *
  * Context:
  *      Kernel context.
+ *      ADAPTER_STATE_LOCK must be already obtained
  */
 static void
 ql_configure_n_port_info(ql_adapter_state_t *ha)
 {
         ql_tgt_t        tmp_tq;
         ql_tgt_t        *tq;
         uint8_t         *cb_port_name;
         ql_link_t       *link;
         int             index, rval;
+        uint16_t                loop_id = 0;
+        uint32_t                found = 0;
+        ql_dev_id_list_t        *list;
+        uint32_t                list_size;
+        ql_mbx_data_t           mr;
+        port_id_t               d_id = {0, 0, 0, 0};
 
-        tq = &tmp_tq;
+        QL_PRINT_10(ha, "started\n");
 
         /* Free existing target queues. */
         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                 link = ha->dev[index].first;
                 while (link != NULL) {
                         tq = link->base_address;
                         link = link->next;
-                        ql_remove_link(&ha->dev[index], &tq->device);
-                        ql_dev_free(ha, tq);
+
+                        /* workaround FW issue, do implicit logout */
+                        /* Never logo to the reused loopid!! */
+                        if ((tq->loop_id != 0x7ff) &&
+                            (tq->loop_id != 0x7fe)) {
+                                if (found == 0) {
+                                        rval = ql_get_port_database(ha,
+                                            tq, PDF_NONE);
+                                        if ((rval == QL_SUCCESS) &&
+                                            (tq->master_state ==
+                                            PD_STATE_PORT_LOGGED_IN)) {
+                                                EL(ha, "nport id (%xh) "
+                                                    "loop_id=%xh "
+                                                    "reappeared\n",
+                                                    tq->d_id.b24,
+                                                    tq->loop_id);
+                                                bcopy((void *)&tq->port_name[0],
+                                                    (void *)&ha->n_port->
+                                                    port_name[0],
+                                                    8);
+                                                bcopy((void *)&tq->node_name[0],
+                                                    (void *)&ha->n_port->
+                                                    node_name[0],
+                                                    8);
+                                                ha->n_port->d_id.b24 =
+                                                    tq->d_id.b24;
+                                                found = 1;
+                                                continue;
                 }
         }
+                                (void) ql_logout_fabric_port(ha, tq);
+                        }
 
+                        tq->loop_id = PORT_NO_LOOP_ID;
+                }
+        }
+
+        if (found == 1) {
+                QL_PRINT_10(ha, "done found\n");
+                return;
+        }
+
+        tq = &tmp_tq;
+
         /*
          * If the N_Port's WWPN is larger than our's then it has the
          * N_Port login initiative.  It will have determined that and
          * logged in with the firmware.  This results in a device
          * database entry.  In this situation we will later send up a PLOGI
@@ -3015,20 +3175,18 @@
         tq->d_id.b.area = 0;
         tq->d_id.b.domain = 0;
         tq->loop_id = 0x7fe;
 
         rval = ql_get_port_database(ha, tq, PDF_NONE);
-        if (rval == QL_SUCCESS || rval == QL_NOT_LOGGED_IN) {
-                ql_dev_id_list_t        *list;
-                uint32_t                list_size;
-                ql_mbx_data_t           mr;
-                port_id_t               d_id = {0, 0, 0, 0};
-                uint16_t                loop_id = 0;
 
-                cb_port_name = (uint8_t *)(CFG_IST(ha, CFG_CTRL_24258081) ?
-                    &ha->init_ctrl_blk.cb24.port_name[0] :
-                    &ha->init_ctrl_blk.cb.port_name[0]);
+        /*
+         * Only collect the P2P remote port information in the case of
+         * QL_SUCCESS. FW should have always logged in (flogi) to remote
+         * port at this point.
+         */
+        if (rval == QL_SUCCESS) {
+                cb_port_name = &ha->loginparams.nport_ww_name.raw_wwn[0];
 
                 if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
                     (la_wwn_t *)cb_port_name) == 1)) {
                         EL(ha, "target port has N_Port login initiative\n");
                 } else {
@@ -3043,23 +3201,27 @@
                     (void *)&ha->n_port->node_name[0], 8);
 
                 /* Resolve an n_port_handle */
                 ha->n_port->n_port_handle = 0x7fe;
 
+        }
+
                 list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
                 list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
 
-                if (list != NULL &&
-                    ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
+        if (ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
                     QL_SUCCESS) {
-                        if (mr.mb[1]) {
-                                EL(ha, "id list entries = %d\n", mr.mb[1]);
-                                for (index = 0; index < mr.mb[1]; index++) {
+                        /* For the p2p mr.mb[1] must be 1 */
+                        if (mr.mb[1] == 1) {
+                                index = 0;
                                         ql_dev_list(ha, list, index,
                                             &d_id, &loop_id);
                                         ha->n_port->n_port_handle = loop_id;
-                                }
+
+                                tq->loop_id = loop_id;
+                                tq->d_id.b24 = d_id.b24;
+                                ha->n_port->d_id.b24 = d_id.b24;
                         } else {
                                 for (index = 0; index <= LAST_LOCAL_LOOP_ID;
                                     index++) {
                                         /* resuse tq */
                                         tq->loop_id = (uint16_t)index;
@@ -3069,27 +3231,68 @@
                                                 if (tq->master_state ==
                                                     PD_STATE_PLOGI_PENDING) {
                                                         ha->n_port->
                                                             n_port_handle =
                                                             tq->loop_id;
+                                                        ha->n_port->d_id.b24 =
+                                                            tq->hard_addr.b24;
                                                         break;
                                                 }
-                                        } else {
+                                        } else if (rval == QL_SUCCESS) {
                                                 ha->n_port->n_port_handle =
                                                     tq->loop_id;
+                                                ha->n_port->d_id.b24 =
+                                                    tq->hard_addr.b24;
+
                                                 break;
                                         }
                                 }
+                                if (index > LAST_LOCAL_LOOP_ID) {
+                                        EL(ha, "P2P:exceeded last id, "
+                                            "n_port_handle = %xh\n",
+                                            ha->n_port->n_port_handle);
+
+                                        ha->n_port->n_port_handle = 0;
+                                        tq->loop_id = 0;
                         }
-                } else {
-                        cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
-                            QL_NAME, ha->instance, d_id.b24);
                 }
-                if (list != NULL) {
+                } else {
                         kmem_free(list, list_size);
+                        EL(ha, "ql_get_dev_list unsuccessful\n");
+                        return;
                 }
+
+                /* with the tq->loop_id to get the port database */
+
+                rval = ql_get_port_database(ha, tq, PDF_NONE);
+
+                if (rval == QL_NOT_LOGGED_IN) {
+                        if (tq->master_state == PD_STATE_PLOGI_PENDING) {
+                                bcopy((void *)&tq->port_name[0],
+                                    (void *)&ha->n_port->port_name[0], 8);
+                                bcopy((void *)&tq->node_name[0],
+                                    (void *)&ha->n_port->node_name[0], 8);
+                                bcopy((void *)&tq->hard_addr,
+                                    (void *)&ha->n_port->d_id,
+                                    sizeof (port_id_t));
+                                ha->n_port->d_id.b24 = d_id.b24;
         }
+                } else if (rval == QL_SUCCESS) {
+                        bcopy((void *)&tq->port_name[0],
+                            (void *)&ha->n_port->port_name[0], 8);
+                        bcopy((void *)&tq->node_name[0],
+                            (void *)&ha->n_port->node_name[0], 8);
+                        bcopy((void *)&tq->hard_addr,
+                            (void *)&ha->n_port->d_id, sizeof (port_id_t));
+                        ha->n_port->d_id.b24 = d_id.b24;
+
+                }
+
+                kmem_free(list, list_size);
+
+                EL(ha, "d_id = %xh, nport_handle = %xh, tq->loop_id = %xh",
+                    tq->d_id.b24, ha->n_port->n_port_handle, tq->loop_id);
 }
 
 
 /*
  * ql_configure_hba
@@ -3110,11 +3313,11 @@
         uint8_t         *bp;
         int             rval;
         uint32_t        state;
         ql_mbx_data_t   mr;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         /* Get host addresses. */
         rval = ql_get_adapter_id(ha, &mr);
         if (rval == QL_SUCCESS) {
                 ha->topology = (uint8_t)(ha->topology &
@@ -3123,63 +3326,70 @@
                 /* Save Host d_id, alpa, loop ID. */
                 ha->loop_id = mr.mb[1];
                 ha->d_id.b.al_pa = LSB(mr.mb[2]);
                 ha->d_id.b.area = MSB(mr.mb[2]);
                 ha->d_id.b.domain = LSB(mr.mb[3]);
+                ha->bbcr_initial = LSB(mr.mb[15]);
+                ha->bbcr_runtime = MSB(mr.mb[15]);
 
                 ADAPTER_STATE_LOCK(ha);
                 ha->flags &= ~FDISC_ENABLED;
+                ADAPTER_STATE_UNLOCK(ha);
 
                 /* Get loop topology. */
                 switch (mr.mb[6]) {
-                case CNX_LOOP_NO_FABRIC:
+                case GID_TOP_NL_PORT:
                         ha->topology = (uint8_t)(ha->topology | QL_NL_PORT);
+                        ha->loop_id = mr.mb[1];
                         break;
-                case CNX_FLPORT_IN_LOOP:
+                case GID_TOP_FL_PORT:
                         ha->topology = (uint8_t)(ha->topology | QL_FL_PORT);
+                        ha->loop_id = mr.mb[1];
                         break;
-                case CNX_NPORT_2_NPORT_P2P:
-                case CNX_NPORT_2_NPORT_NO_TGT_RSP:
+                case GID_TOP_N_PORT:
+                case GID_TOP_N_PORT_NO_TGT:
                         ha->flags |= POINT_TO_POINT;
                         ha->topology = (uint8_t)(ha->topology | QL_N_PORT);
-                        if (CFG_IST(ha, CFG_CTRL_2425)) {
+                        ha->loop_id = 0xffff;
+                        if (CFG_IST(ha, CFG_N2N_SUPPORT)) {
                                 ql_configure_n_port_info(ha);
                         }
                         break;
-                case CNX_FLPORT_P2P:
+                case GID_TOP_F_PORT:
                         ha->flags |= POINT_TO_POINT;
                         ha->topology = (uint8_t)(ha->topology | QL_F_PORT);
+                        ha->loop_id = 0xffff;
 
                         /* Get supported option. */
-                        if (CFG_IST(ha, CFG_CTRL_24258081) &&
+                        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2) &&
                             mr.mb[7] & GID_FP_NPIV_SUPPORT) {
+                                ADAPTER_STATE_LOCK(ha);
                                 ha->flags |= FDISC_ENABLED;
+                                ADAPTER_STATE_UNLOCK(ha);
                         }
                         /* Get VLAN ID, mac address */
-                        if (CFG_IST(ha, CFG_CTRL_8081)) {
+                        if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
+                                ha->flags |= FDISC_ENABLED;
                                 ha->fabric_params = mr.mb[7];
                                 ha->fcoe_vlan_id = (uint16_t)(mr.mb[9] & 0xfff);
                                 ha->fcoe_fcf_idx = mr.mb[10];
-                                ha->fcoe_vnport_mac[0] = MSB(mr.mb[11]);
-                                ha->fcoe_vnport_mac[1] = LSB(mr.mb[11]);
-                                ha->fcoe_vnport_mac[2] = MSB(mr.mb[12]);
-                                ha->fcoe_vnport_mac[3] = LSB(mr.mb[12]);
-                                ha->fcoe_vnport_mac[4] = MSB(mr.mb[13]);
-                                ha->fcoe_vnport_mac[5] = LSB(mr.mb[13]);
+                                ha->fcoe_vnport_mac[5] = MSB(mr.mb[11]);
+                                ha->fcoe_vnport_mac[4] = LSB(mr.mb[11]);
+                                ha->fcoe_vnport_mac[3] = MSB(mr.mb[12]);
+                                ha->fcoe_vnport_mac[2] = LSB(mr.mb[12]);
+                                ha->fcoe_vnport_mac[1] = MSB(mr.mb[13]);
+                                ha->fcoe_vnport_mac[0] = LSB(mr.mb[13]);
                         }
                         break;
                 default:
-                        QL_PRINT_2(CE_CONT, "(%d,%d): UNKNOWN topology=%xh, "
-                            "d_id=%xh\n", ha->instance, ha->vp_index, mr.mb[6],
-                            ha->d_id.b24);
+                        QL_PRINT_2(ha, "UNKNOWN topology=%xh, d_id=%xh\n",
+                            mr.mb[6], ha->d_id.b24);
                         rval = QL_FUNCTION_FAILED;
                         break;
                 }
-                ADAPTER_STATE_UNLOCK(ha);
 
-                if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322 |
-                    CFG_CTRL_24258081))) {
+                if (CFG_IST(ha, CFG_CTRL_2363 | CFG_ISP_FW_TYPE_2)) {
                         mr.mb[1] = 0;
                         mr.mb[2] = 0;
                         rval = ql_data_rate(ha, &mr);
                         if (rval != QL_SUCCESS) {
                                 EL(ha, "data_rate status=%xh\n", rval);
@@ -3194,10 +3404,14 @@
                                         state = FC_STATE_4GBIT_SPEED;
                                 } else if (mr.mb[1] == IIDMA_RATE_8GB) {
                                         state = FC_STATE_8GBIT_SPEED;
                                 } else if (mr.mb[1] == IIDMA_RATE_10GB) {
                                         state = FC_STATE_10GBIT_SPEED;
+                                } else if (mr.mb[1] == IIDMA_RATE_16GB) {
+                                        state = FC_STATE_16GBIT_SPEED;
+                                } else if (mr.mb[1] == IIDMA_RATE_32GB) {
+                                        state = FC_STATE_32GBIT_SPEED;
                                 } else {
                                         state = 0;
                                 }
                         }
                 } else {
@@ -3212,11 +3426,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 bp = ha->loginparams.nport_ww_name.raw_wwn;
-                EL(ha, "topology=%xh, d_id=%xh, "
+                EL(ha, "topology=%xh, hba port id=%xh, "
                     "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n",
                     ha->topology, ha->d_id.b24, bp[0], bp[1],
                     bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]);
         }
         return (rval);
@@ -3248,11 +3462,11 @@
         uint32_t                list_size;
         uint16_t                index, loop_id;
         ql_mbx_data_t           mr;
         uint8_t                 retries = MAX_DEVICE_LOST_RETRY;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
         list = kmem_zalloc(list_size, KM_SLEEP);
         if (list == NULL) {
                 rval = QL_MEMORY_ALLOC_FAILED;
@@ -3269,122 +3483,122 @@
                         kmem_free(list, list_size);
                         EL(ha, "failed, rval = %xh\n", rval);
                         return (rval);
                 }
 
-                /* Acquire adapter state lock. */
-                ADAPTER_STATE_LOCK(ha);
-
-                /* Mark all queues as unusable. */
+                /*
+                 * Mark queues as unusable selectively.
+                 * If the current topology is AL, only fabric tgt queues
+                 * are marked as unusable and eventually removed.
+                 * If the current topology is P2P, all fabric tgt queues
+                 * are processed in ql_configure_n_port_info().
+                 * If the current topology is Fabric, all previous created
+                 * non-fabric device should be marked as lost and eventually
+                 * should be removed.
+                 */
                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
                         for (link = ha->dev[index].first; link != NULL;
                             link = link->next) {
                                 tq = link->base_address;
+
+                                if (VALID_DEVICE_ID(ha, tq->loop_id)) {
                                 DEVICE_QUEUE_LOCK(tq);
                                 if (!(tq->flags & TQF_PLOGI_PROGRS) &&
                                     !(ha->topology & QL_N_PORT)) {
                                         tq->loop_id = (uint16_t)
-                                            (tq->loop_id | PORT_LOST_ID);
+                                                    (tq->loop_id |
+                                                    PORT_LOST_ID);
                                 }
+                                        if ((ha->topology & QL_NL_PORT) &&
+                                            (tq->flags & TQF_FABRIC_DEVICE)) {
+                                                tq->loop_id = (uint16_t)
+                                                    (tq->loop_id |
+                                                    PORT_LOST_ID);
+                                        }
                                 DEVICE_QUEUE_UNLOCK(tq);
                         }
                 }
+                }
 
                 /* If device not in queues add new queue. */
                 for (index = 0; index < mr.mb[1]; index++) {
                         ql_dev_list(ha, list, index, &d_id, &loop_id);
 
                         if (VALID_DEVICE_ID(ha, loop_id)) {
+                                ADAPTER_STATE_LOCK(ha);
                                 tq = ql_dev_init(ha, d_id, loop_id);
+                                ADAPTER_STATE_UNLOCK(ha);
                                 if (tq != NULL) {
                                         tq->loop_id = loop_id;
 
                                         /* Test for fabric device. */
-                                        if (d_id.b.domain !=
+                                        if (ha->topology & QL_F_PORT ||
+                                            d_id.b.domain !=
                                             ha->d_id.b.domain ||
                                             d_id.b.area != ha->d_id.b.area) {
                                                 tq->flags |= TQF_FABRIC_DEVICE;
                                         }
 
-                                        ADAPTER_STATE_UNLOCK(ha);
                                         if (ql_get_port_database(ha, tq,
                                             PDF_NONE) == QL_SUCCESS) {
-                                                ADAPTER_STATE_LOCK(ha);
                                                 tq->loop_id = (uint16_t)
                                                     (tq->loop_id &
                                                     ~PORT_LOST_ID);
-                                        } else {
-                                                ADAPTER_STATE_LOCK(ha);
                                         }
                                 }
                         }
                 }
 
                 /* 24xx does not report switch devices in ID list. */
-                if ((CFG_IST(ha, CFG_CTRL_24258081)) &&
-                    ha->topology & (QL_F_PORT | QL_FL_PORT)) {
-                        d_id.b24 = 0xfffffe;
+                if (CFG_IST(ha, CFG_ISP_FW_TYPE_2) &&
+                    ha->topology & QL_FABRIC_CONNECTION) {
+                        d_id.b24 = FS_FABRIC_F_PORT;
+                        ADAPTER_STATE_LOCK(ha);
                         tq = ql_dev_init(ha, d_id, FL_PORT_24XX_HDL);
+                        ADAPTER_STATE_UNLOCK(ha);
                         if (tq != NULL) {
                                 tq->flags |= TQF_FABRIC_DEVICE;
-                                ADAPTER_STATE_UNLOCK(ha);
                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
-                                ADAPTER_STATE_LOCK(ha);
                         }
-                        d_id.b24 = 0xfffffc;
+
+                        d_id.b24 = FS_NAME_SERVER;
+                        ADAPTER_STATE_LOCK(ha);
                         tq = ql_dev_init(ha, d_id, SNS_24XX_HDL);
+                        ADAPTER_STATE_UNLOCK(ha);
                         if (tq != NULL) {
                                 tq->flags |= TQF_FABRIC_DEVICE;
-                                ADAPTER_STATE_UNLOCK(ha);
                                 if (ha->vp_index != 0) {
                                         (void) ql_login_fport(ha, tq,
                                             SNS_24XX_HDL, LFF_NONE, NULL);
                                 }
                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
-                                ADAPTER_STATE_LOCK(ha);
                         }
                 }
 
-                /* If F_port exists, allocate queue for FL_Port. */
-                index = ql_alpa_to_index[0xfe];
-                d_id.b24 = 0;
-                if (ha->dev[index].first != NULL) {
-                        tq = ql_dev_init(ha, d_id, (uint16_t)
-                            (CFG_IST(ha, CFG_CTRL_24258081) ?
-                            FL_PORT_24XX_HDL : FL_PORT_LOOP_ID));
-                        if (tq != NULL) {
-                                tq->flags |= TQF_FABRIC_DEVICE;
-                                ADAPTER_STATE_UNLOCK(ha);
-                                (void) ql_get_port_database(ha, tq, PDF_NONE);
-                                ADAPTER_STATE_LOCK(ha);
-                        }
-                }
-
                 /* Allocate queue for broadcast. */
-                d_id.b24 = 0xffffff;
+                d_id.b24 = FS_BROADCAST;
+                ADAPTER_STATE_LOCK(ha);
                 (void) ql_dev_init(ha, d_id, (uint16_t)
-                    (CFG_IST(ha, CFG_CTRL_24258081) ? BROADCAST_24XX_HDL :
+                    (CFG_IST(ha, CFG_ISP_FW_TYPE_2) ? BROADCAST_24XX_HDL :
                     IP_BROADCAST_LOOP_ID));
+                ADAPTER_STATE_UNLOCK(ha);
 
-                /* Check for any devices lost. */
+                /*
+                 * Topology change (fabric<->p2p),(fabric<->al)
+                 * (al<->p2p) have to be taken care of.
+                 */
                 loop = FALSE;
                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
-                        for (link = ha->dev[index].first; link != NULL;
-                            link = link->next) {
-                                tq = link->base_address;
+                        ql_update_dev(ha, index);
+                }
 
-                                if ((tq->loop_id & PORT_LOST_ID) &&
-                                    !(tq->flags & (TQF_INITIATOR_DEVICE |
-                                    TQF_FABRIC_DEVICE))) {
+                if ((ha->topology & QL_NL_PORT) && (mr.mb[1] != 0)) {
+                        loop = FALSE;
+                } else if (mr.mb[1] == 0 && !(ha->topology & QL_F_PORT)) {
                                         loop = TRUE;
                                 }
-                        }
-                }
 
-                /* Release adapter state lock. */
-                ADAPTER_STATE_UNLOCK(ha);
-
                 /* Give devices time to recover. */
                 if (loop == TRUE) {
                         drv_usecwait(1000000);
                 }
         } while (retries-- && loop == TRUE &&
@@ -3394,11 +3608,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
 
         return (rval);
 }
 
@@ -3418,11 +3632,11 @@
  */
 void
 ql_dev_list(ql_adapter_state_t *ha, union ql_dev_id_list *list,
     uint32_t index, port_id_t *d_id, uint16_t *id)
 {
-        if (CFG_IST(ha, CFG_CTRL_24258081)) {
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 struct ql_24_dev_id     *list24 = (struct ql_24_dev_id *)list;
 
                 d_id->b.al_pa = list24[index].al_pa;
                 d_id->b.area = list24[index].area;
                 d_id->b.domain = list24[index].domain;
@@ -3466,14 +3680,13 @@
 {
         port_id_t       d_id;
         ql_tgt_t        *tq;
         int             rval = QL_FUNCTION_FAILED;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
-        ha->topology = (uint8_t)(ha->topology & ~QL_SNS_CONNECTION);
-
+        if (ha->topology & QL_FABRIC_CONNECTION) {
         /* Test switch fabric controller present. */
         d_id.b24 = FS_FABRIC_F_PORT;
         tq = ql_d_id_to_queue(ha, d_id);
         if (tq != NULL) {
                 /* Get port/node names of F_Port. */
@@ -3481,21 +3694,20 @@
 
                 d_id.b24 = FS_NAME_SERVER;
                 tq = ql_d_id_to_queue(ha, d_id);
                 if (tq != NULL) {
                         (void) ql_get_port_database(ha, tq, PDF_NONE);
-                        ha->topology = (uint8_t)
-                            (ha->topology | QL_SNS_CONNECTION);
                         rval = QL_SUCCESS;
                 }
         }
+        }
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed=%xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -3515,45 +3727,42 @@
 {
         uint32_t                cnt;
         uint16_t                cmd;
         ql_adapter_state_t      *ha = vha->pha;
 
-        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+        QL_PRINT_10(ha, "started\n");
 
         /*
          * accessing pci space while not powered can cause panic's
          * on some platforms (i.e. Sunblade 1000's)
          */
         if (ha->power_level == PM_LEVEL_D3) {
-                QL_PRINT_2(CE_CONT, "(%d): Low Power exit\n", ha->instance);
+                QL_PRINT_2(ha, "Low Power exit\n");
                 return;
         }
 
+        /* Disable ISP interrupts. */
+        ql_disable_intr(ha);
+
         /* Reset all outbound mailbox registers */
         for (cnt = 0; cnt < ha->reg_off->mbox_cnt; cnt++) {
                 WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
         }
 
-        if (CFG_IST(ha, CFG_CTRL_8021)) {
+        if (CFG_IST(ha, CFG_CTRL_82XX)) {
                 ha->timeout_cnt = 0;
                 ql_8021_reset_chip(ha);
-                QL_PRINT_3(CE_CONT, "(%d): 8021 exit\n", ha->instance);
+                QL_PRINT_10(ha, "8021 exit\n");
                 return;
         }
 
-        /* Disable ISP interrupts. */
-        WRT16_IO_REG(ha, ictrl, 0);
-        ADAPTER_STATE_LOCK(ha);
-        ha->flags &= ~INTERRUPTS_ENABLED;
-        ADAPTER_STATE_UNLOCK(ha);
-
-        if (CFG_IST(ha, CFG_CTRL_242581)) {
-                RD32_IO_REG(ha, ictrl);
+        if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
                 ql_reset_24xx_chip(ha);
-                QL_PRINT_3(CE_CONT, "(%d): 24xx exit\n", ha->instance);
+                QL_PRINT_10(ha, "24xx exit\n");
                 return;
         }
+        QL_PRINT_10(ha, "CFG_ISP_FW_TYPE_1 reset\n");
 
         /*
          * We are going to reset the chip in case of 2300. That might cause
          * a PBM ERR if a DMA transaction is in progress. One way of
          * avoiding it is to disable Bus Master operation before we start
@@ -3586,19 +3795,19 @@
 
         /* FPM Soft Reset. */
         WRT16_IO_REG(ha, fpm_diag_config, 0x100);
 
         /* Toggle FPM reset for 2300 */
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 WRT16_IO_REG(ha, fpm_diag_config, 0);
         }
 
         /* Select frame buffer registers. */
         WRT16_IO_REG(ha, ctrl_status, 0x10);
 
         /* Reset frame buffer FIFOs. */
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 WRT16_IO_REG(ha, fb_cmd, 0x00fc);
                 /* read back fb_cmd until zero or 3 seconds max */
                 for (cnt = 0; cnt < 300000; cnt++) {
                         if ((RD16_IO_REG(ha, fb_cmd) & 0xff) == 0) {
                                 break;
@@ -3624,17 +3833,21 @@
         /* Insure mailbox registers are free. */
         WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
         WRT16_IO_REG(ha, hccr, HC_CLR_HOST_INT);
 
         /* clear the mailbox command pointer. */
-        ql_clear_mcp(ha);
+        INTR_LOCK(ha);
+        ha->mcp = NULL;
+        INTR_UNLOCK(ha);
 
+        MBX_REGISTER_LOCK(ha);
         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
             ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
+        MBX_REGISTER_UNLOCK(ha);
 
         /* Bus Master is disabled so chip reset is safe. */
-        if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
+        if (CFG_IST(ha, CFG_CTRL_2363)) {
                 WRT16_IO_REG(ha, ctrl_status, ISP_RESET);
                 drv_usecwait(MILLISEC);
 
                 /* Wait for reset to finish. */
                 for (cnt = 0; cnt < 30000; cnt++) {
@@ -3645,11 +3858,11 @@
                 }
         }
 
         /* Wait for RISC to recover from reset. */
         for (cnt = 0; cnt < 30000; cnt++) {
-                if (RD16_IO_REG(ha, mailbox_out[0]) != MBS_BUSY) {
+                if (RD16_IO_REG(ha, mailbox_out[0]) != MBS_ROM_BUSY) {
                         break;
                 }
                 drv_usecwait(MILLISEC);
         }
 
@@ -3659,10 +3872,15 @@
         ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
 
         /* Disable RISC pause on FPM parity error. */
         WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
 
+        if (CFG_IST(ha, CFG_CTRL_22XX) &&
+            RD16_IO_REG(ha, mailbox_out[7]) == 4) {
+                ha->fw_transfer_size = 128;
+        }
+
         /* Initialize probe registers */
         if (CFG_IST(ha, CFG_SBUS_CARD)) {
                 /* Pause RISC. */
                 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
                 for (cnt = 0; cnt < 30000; cnt++) {
@@ -3684,11 +3902,11 @@
 
                 /* Release RISC module. */
                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
         }
 
-        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+        QL_PRINT_10(ha, "done\n");
 }
 
 /*
  * ql_reset_24xx_chip
  *      Reset ISP24xx chip.
@@ -3698,17 +3916,23 @@
  *      All activity on chip must be already stopped.
  *
  * Context:
  *      Interrupt or Kernel context, no mailbox commands allowed.
  */
-void
+static void
 ql_reset_24xx_chip(ql_adapter_state_t *ha)
 {
         uint32_t        timer, stat;
 
+        QL_PRINT_10(ha, "started\n");
+
         /* Shutdown DMA. */
+        if (CFG_IST(ha, CFG_MWB_4096_SUPPORT)) {
         WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN | MWB_4096_BYTES);
+        } else {
+                WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN);
+        }
 
         /* Wait for DMA to stop. */
         for (timer = 0; timer < 30000; timer++) {
                 if ((RD32_IO_REG(ha, ctrl_status) & DMA_ACTIVE) == 0) {
                         break;
@@ -3717,10 +3941,18 @@
         }
 
         /* Stop the firmware. */
         WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
         WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
+        WRT16_IO_REG(ha, mailbox_in[1], 0);
+        WRT16_IO_REG(ha, mailbox_in[2], 0);
+        WRT16_IO_REG(ha, mailbox_in[3], 0);
+        WRT16_IO_REG(ha, mailbox_in[4], 0);
+        WRT16_IO_REG(ha, mailbox_in[5], 0);
+        WRT16_IO_REG(ha, mailbox_in[6], 0);
+        WRT16_IO_REG(ha, mailbox_in[7], 0);
+        WRT16_IO_REG(ha, mailbox_in[8], 0);
         WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
         for (timer = 0; timer < 30000; timer++) {
                 stat = RD32_IO_REG(ha, risc2host);
                 if (stat & BIT_15) {
                         if ((stat & 0xff) < 0x12) {
@@ -3731,19 +3963,28 @@
                 }
                 drv_usecwait(100);
         }
 
         /* Reset the chip. */
-        WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
-            MWB_4096_BYTES);
+        WRT32_IO_REG(ha, ctrl_status, ISP_RESET);
         drv_usecwait(100);
 
+        /* Wait for RISC to recover from reset. */
+        for (timer = 30000; timer; timer--) {
+                ha->rom_status = RD16_IO_REG(ha, mailbox_out[0]);
+                if (CFG_IST(ha, CFG_CTRL_278083)) {
+                        /* Wait for RISC to recover from reset. */
+                        if ((ha->rom_status & MBS_ROM_STATUS_MASK) !=
+                            MBS_ROM_BUSY) {
+                                break;
+                        }
+                } else {
         /* Wait for idle status from ROM firmware. */
-        for (timer = 0; timer < 30000; timer++) {
-                if (RD16_IO_REG(ha, mailbox_out[0]) == 0) {
+                        if (ha->rom_status == MBS_ROM_IDLE) {
                         break;
                 }
+                }
                 drv_usecwait(100);
         }
 
         /* Wait for reset to finish. */
         for (timer = 0; timer < 30000; timer++) {
@@ -3751,16 +3992,29 @@
                         break;
                 }
                 drv_usecwait(100);
         }
 
+        ha->adapter_stats->revlvl.isp2200 = RD16_IO_REG(ha, mailbox_out[4]);
+        ha->adapter_stats->revlvl.risc = RD16_IO_REG(ha, mailbox_out[5]);
+        ha->adapter_stats->revlvl.frmbfr = RD16_IO_REG(ha, mailbox_out[6]);
+        ha->adapter_stats->revlvl.riscrom = RD16_IO_REG(ha, mailbox_out[8]);
+
+        /* Insure mailbox registers are free. */
+        WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
+        WRT32_IO_REG(ha, hccr, HC24_CLR_HOST_INT);
+
         /* clear the mailbox command pointer. */
-        ql_clear_mcp(ha);
+        INTR_LOCK(ha);
+        ha->mcp = NULL;
+        INTR_UNLOCK(ha);
 
         /* Insure mailbox registers are free. */
+        MBX_REGISTER_LOCK(ha);
         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
             ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
+        MBX_REGISTER_UNLOCK(ha);
 
         if (ha->flags & MPI_RESET_NEEDED) {
                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
                 WRT16_IO_REG(ha, mailbox_in[0], MBC_RESTART_MPI);
                 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
@@ -3779,52 +4033,14 @@
                 ADAPTER_STATE_LOCK(ha);
                 ha->flags &= ~MPI_RESET_NEEDED;
                 ADAPTER_STATE_UNLOCK(ha);
         }
 
-        /*
-         * Set flash write-protection.
-         */
-        if ((ha->flags & ONLINE) == 0) {
-                ql_24xx_protect_flash(ha);
-        }
+        QL_PRINT_10(ha, "done\n");
 }
 
 /*
- * ql_clear_mcp
- *      Carefully clear the mailbox command pointer in the ha struct.
- *
- * Input:
- *      ha = adapter block pointer.
- *
- * Context:
- *      Interrupt or Kernel context, no mailbox commands allowed.
- */
-
-static void
-ql_clear_mcp(ql_adapter_state_t *ha)
-{
-        uint32_t cnt;
-
-        /* Don't null ha->mcp without the lock, but don't hang either. */
-        if (MBX_REGISTER_LOCK_OWNER(ha) == curthread) {
-                ha->mcp = NULL;
-        } else {
-                for (cnt = 0; cnt < 300000; cnt++) {
-                        if (TRY_MBX_REGISTER_LOCK(ha) != 0) {
-                                ha->mcp = NULL;
-                                MBX_REGISTER_UNLOCK(ha);
-                                break;
-                        } else {
-                                drv_usecwait(10);
-                        }
-                }
-        }
-}
-
-
-/*
  * ql_abort_isp
  *      Resets ISP and aborts all outstanding commands.
  *
  * Input:
  *      ha = adapter state pointer.
@@ -3838,39 +4054,46 @@
  */
 int
 ql_abort_isp(ql_adapter_state_t *vha)
 {
         ql_link_t               *link, *link2;
-        ddi_devstate_t          state;
         uint16_t                index;
         ql_tgt_t                *tq;
         ql_lun_t                *lq;
-        ql_srb_t                *sp;
         int                     rval = QL_SUCCESS;
         ql_adapter_state_t      *ha = vha->pha;
+        boolean_t               abort_loop_down = B_FALSE;
 
-        QL_PRINT_2(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_2(ha, "started\n");
 
         TASK_DAEMON_LOCK(ha);
         ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
         if (ha->task_daemon_flags & ABORT_ISP_ACTIVE ||
             (ha->flags & ONLINE) == 0 || ha->flags & ADAPTER_SUSPENDED) {
                 TASK_DAEMON_UNLOCK(ha);
+                QL_PRINT_2(ha, "already active or suspended tdf=0x%llx, "
+                    "flgs=0x%llx\n", ha->task_daemon_flags, ha->flags);
                 return (rval);
         }
 
         ha->task_daemon_flags |= ABORT_ISP_ACTIVE;
-        ha->task_daemon_flags &= ~(RESET_MARKER_NEEDED | FIRMWARE_UP |
+        ha->task_daemon_flags &= ~(MARKER_NEEDED | FIRMWARE_UP |
             FIRMWARE_LOADED);
         for (vha = ha; vha != NULL; vha = vha->vp_next) {
-                vha->task_daemon_flags |= LOOP_DOWN;
                 vha->task_daemon_flags &= ~(COMMAND_WAIT_NEEDED |
                     LOOP_RESYNC_NEEDED);
+                vha->task_daemon_flags |= LOOP_DOWN;
+                if (vha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
+                        abort_loop_down = B_TRUE;
+                        vha->loop_down_timer = LOOP_DOWN_TIMER_START;
         }
+        }
 
         TASK_DAEMON_UNLOCK(ha);
 
+        ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
+
         if (ha->mailbox_flags & MBX_BUSY_FLG) {
                 /* Acquire mailbox register lock. */
                 MBX_REGISTER_LOCK(ha);
 
                 /* Wake up mailbox box routine. */
@@ -3881,11 +4104,11 @@
                 MBX_REGISTER_UNLOCK(ha);
 
                 /* Wait for mailbox. */
                 for (index = 100; index &&
                     ha->mailbox_flags & MBX_ABORT; index--) {
-                        drv_usecwait(50000);
+                        delay(1);
                 }
         }
 
         /* Wait for commands to end gracefully if not in panic. */
         if (ha->flags & PARITY_ERROR) {
@@ -3894,17 +4117,31 @@
                 ADAPTER_STATE_UNLOCK(ha);
         } else if (ddi_in_panic() == 0) {
                 ql_cmd_wait(ha);
         }
 
+        rval = QL_ABORTED;
+        if (ha->flags & FW_DUMP_NEEDED) {
+                rval = ql_binary_fw_dump(ha, TRUE);
+        }
+
         /* Shutdown IP. */
         if (ha->flags & IP_INITIALIZED) {
                 (void) ql_shutdown_ip(ha);
         }
 
+        if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
+                TASK_DAEMON_LOCK(ha);
+                ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
+                TASK_DAEMON_UNLOCK(ha);
+        }
+
         /* Reset the chip. */
+        if (rval != QL_SUCCESS) {
+                rval = QL_SUCCESS;
         ql_reset_chip(ha);
+        }
 
         /*
          * Even though we have waited for outstanding commands to complete,
          * except for ones marked SRB_COMMAND_TIMEOUT, and reset the ISP,
          * there could still be an interrupt thread active.  The interrupt
@@ -3911,70 +4148,13 @@
          * lock will prevent us from getting an sp from the outstanding
          * cmds array that the ISR may be using.
          */
 
         /* Place all commands in outstanding cmd list on device queue. */
-        for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
-                REQUEST_RING_LOCK(ha);
-                INTR_LOCK(ha);
-                if ((link = ha->pending_cmds.first) != NULL) {
-                        sp = link->base_address;
-                        ql_remove_link(&ha->pending_cmds, &sp->cmd);
+        ql_requeue_all_cmds(ha);
 
-                        REQUEST_RING_UNLOCK(ha);
-                        index = 0;
-                } else {
-                        REQUEST_RING_UNLOCK(ha);
-                        if ((sp = ha->outstanding_cmds[index]) == NULL) {
-                                INTR_UNLOCK(ha);
-                                continue;
-                        }
-                }
-
                 /*
-                 * It's not obvious but the index for commands pulled from
-                 * pending will be zero and that entry in the outstanding array
-                 * is not used so nulling it is "no harm, no foul".
-                 */
-
-                ha->outstanding_cmds[index] = NULL;
-                sp->handle = 0;
-                sp->flags &= ~SRB_IN_TOKEN_ARRAY;
-
-                INTR_UNLOCK(ha);
-
-                /* If command timeout. */
-                if (sp->flags & SRB_COMMAND_TIMEOUT) {
-                        sp->pkt->pkt_reason = CS_TIMEOUT;
-                        sp->flags &= ~SRB_RETRY;
-                        sp->flags |= SRB_ISP_COMPLETED;
-
-                        /* Call done routine to handle completion. */
-                        ql_done(&sp->cmd);
-                        continue;
-                }
-
-                /* Acquire target queue lock. */
-                lq = sp->lun_queue;
-                tq = lq->target_queue;
-                DEVICE_QUEUE_LOCK(tq);
-
-                /* Reset watchdog time. */
-                sp->wdg_q_time = sp->init_wdg_q_time;
-
-                /* Place request back on top of device queue. */
-                sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED |
-                    SRB_RETRY);
-
-                ql_add_link_t(&lq->cmd, &sp->cmd);
-                sp->flags |= SRB_IN_DEVICE_QUEUE;
-
-                /* Release target queue lock. */
-                DEVICE_QUEUE_UNLOCK(tq);
-        }
-
-        /*
          * Clear per LUN active count, because there should not be
          * any IO outstanding at this time.
          */
         for (vha = ha; vha != NULL; vha = vha->vp_next) {
                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
@@ -3995,79 +4175,171 @@
                         }
                 }
         }
 
         if ((rval = ql_check_isp_firmware(ha)) != QL_SUCCESS) {
-                if ((rval = ql_chip_diag(ha)) == QL_SUCCESS) {
+                if (ha->dev_state != NX_DEV_READY) {
+                        EL(ha, "dev_state not ready\n");
+                } else if ((rval = ql_mbx_wrap_test(ha, NULL)) == QL_SUCCESS) {
                         rval = ql_load_isp_firmware(ha);
                 }
         }
 
         if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
             QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS &&
             (rval = ql_fw_ready(ha, 10)) == QL_SUCCESS) {
 
+                /* Enable ISP interrupts. */
+                if (!(ha->flags & INTERRUPTS_ENABLED)) {
+                        ql_enable_intr(ha);
+                }
+
                 /* If reset abort needed that may have been set. */
                 TASK_DAEMON_LOCK(ha);
                 ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED |
                     ABORT_ISP_ACTIVE);
                 TASK_DAEMON_UNLOCK(ha);
 
-                /* Enable ISP interrupts. */
-                if (CFG_IST(ha, CFG_CTRL_8021)) {
-                        ql_8021_enable_intrs(ha);
-                } else if (CFG_IST(ha, CFG_CTRL_242581)) {
-                        WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
-                } else {
-                        WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
-                }
-
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags |= INTERRUPTS_ENABLED;
-                ADAPTER_STATE_UNLOCK(ha);
-
                 /* Set loop online, if it really is. */
                 ql_loop_online(ha);
-
-                state = ddi_get_devstate(ha->dip);
-                if (state != DDI_DEVSTATE_UP) {
-                        /*EMPTY*/
-                        ddi_dev_report_fault(ha->dip, DDI_SERVICE_RESTORED,
-                            DDI_DEVICE_FAULT, "Device reset succeeded");
-                }
         } else {
                 /* Enable ISP interrupts. */
-                if (CFG_IST(ha, CFG_CTRL_8021)) {
-                        ql_8021_enable_intrs(ha);
-                } else if (CFG_IST(ha, CFG_CTRL_242581)) {
-                        WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
-                } else {
-                        WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
+                if (!(ha->flags & INTERRUPTS_ENABLED)) {
+                        ql_enable_intr(ha);
                 }
 
-                ADAPTER_STATE_LOCK(ha);
-                ha->flags |= INTERRUPTS_ENABLED;
-                ADAPTER_STATE_UNLOCK(ha);
-
                 TASK_DAEMON_LOCK(ha);
-                ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE);
-                ha->task_daemon_flags |= LOOP_DOWN;
+                for (vha = ha; vha != NULL; vha = vha->vp_next) {
+                        vha->task_daemon_flags |= LOOP_DOWN;
+                }
+                ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
                 TASK_DAEMON_UNLOCK(ha);
 
                 ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
+
+                ql_abort_queues(ha);
+
+                TASK_DAEMON_LOCK(ha);
+                ha->task_daemon_flags &= ~ABORT_ISP_ACTIVE;
+                TASK_DAEMON_UNLOCK(ha);
         }
 
+        for (vha = ha; vha != NULL; vha = vha->vp_next) {
+                if (!(vha->task_daemon_flags & LOOP_DOWN) &&
+                    abort_loop_down == B_TRUE) {
+                        vha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
+                }
+        }
+
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_2(CE_CONT, "(%d): done\n", ha->instance);
+                QL_PRINT_2(ha, "done\n");
         }
         return (rval);
 }
 
 /*
+ * ql_requeue_all_cmds
+ *      Requeue all commands.
+ *
+ * Input:
+ *      ha = virtual adapter state pointer.
+ *
+ * Returns:
+ *      ql local function return status code.
+ *
+ * Context:
+ *      Kernel context.
+ */
+void
+ql_requeue_all_cmds(ql_adapter_state_t *ha)
+{
+        ql_link_t       *link;
+        ql_tgt_t        *tq;
+        ql_lun_t        *lq;
+        ql_srb_t        *sp;
+        uint16_t        index;
+
+        /* Place all commands in outstanding cmd list on device queue. */
+        for (index = 1; index < ha->osc_max_cnt; index++) {
+                INTR_LOCK(ha);
+                REQUEST_RING_LOCK(ha);
+                if ((link = ha->pending_cmds.first) != NULL) {
+                        sp = link->base_address;
+                        ql_remove_link(&ha->pending_cmds, &sp->cmd);
+
+                        REQUEST_RING_UNLOCK(ha);
+                        index = 0;
+                } else {
+                        REQUEST_RING_UNLOCK(ha);
+                        if ((sp = ha->outstanding_cmds[index]) == NULL ||
+                            sp == QL_ABORTED_SRB(ha)) {
+                                INTR_UNLOCK(ha);
+                                continue;
+                        }
+                }
+
+                /*
+                 * It's not obvious but the index for commands pulled from
+                 * pending will be zero and that entry in the outstanding array
+                 * is not used so nulling it is "no harm, no foul".
+                 */
+
+                ha->outstanding_cmds[index] = NULL;
+                sp->handle = 0;
+                sp->flags &= ~SRB_IN_TOKEN_ARRAY;
+
+                INTR_UNLOCK(ha);
+
+                /* If command timeout. */
+                if (sp->flags & SRB_COMMAND_TIMEOUT) {
+                        sp->pkt->pkt_reason = CS_TIMEOUT;
+                        sp->flags &= ~SRB_RETRY;
+                        sp->flags |= SRB_ISP_COMPLETED;
+
+                        /* Call done routine to handle completion. */
+                        ql_done(&sp->cmd, B_FALSE);
+                        continue;
+                }
+
+                /* Acquire target queue lock. */
+                lq = sp->lun_queue;
+                tq = lq->target_queue;
+
+                /* return any tape IO as exchange dropped due to chip reset */
+                if (tq->flags & TQF_TAPE_DEVICE) {
+                        sp->pkt->pkt_reason = CS_TRANSPORT;
+                        sp->flags &= ~SRB_RETRY;
+                        sp->flags |= SRB_ISP_COMPLETED;
+
+                        EL(ha, "rtn seq IO, sp=%ph", sp);
+
+                        /* Call done routine to handle completion. */
+                        ql_done(&sp->cmd, B_FALSE);
+                        continue;
+                }
+
+                DEVICE_QUEUE_LOCK(tq);
+
+                /* Reset watchdog time. */
+                sp->wdg_q_time = sp->init_wdg_q_time;
+
+                /* Place request back on top of device queue. */
+                sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED |
+                    SRB_RETRY);
+
+                ql_add_link_t(&lq->cmd, &sp->cmd);
+                sp->flags |= SRB_IN_DEVICE_QUEUE;
+
+                /* Release target queue lock. */
+                DEVICE_QUEUE_UNLOCK(tq);
+        }
+}
+
+/*
  * ql_vport_control
  *      Issue Virtual Port Control command.
  *
  * Input:
  *      ha = virtual adapter state pointer.
@@ -4085,11 +4357,11 @@
         ql_mbx_iocb_t   *pkt;
         uint8_t         bit;
         int             rval;
         uint32_t        pkt_size;
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         if (ha->vp_index != 0) {
                 pkt_size = sizeof (ql_mbx_iocb_t);
                 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
                 if (pkt == NULL) {
@@ -4099,10 +4371,11 @@
 
                 pkt->vpc.entry_type = VP_CONTROL_TYPE;
                 pkt->vpc.entry_count = 1;
                 pkt->vpc.command = cmd;
                 pkt->vpc.vp_count = 1;
+                pkt->vpc.fcf_index = ha->fcoe_fcf_idx;
                 bit = (uint8_t)(ha->vp_index - 1);
                 pkt->vpc.vp_index[bit / 8] = (uint8_t)
                     (pkt->vpc.vp_index[bit / 8] | BIT_0 << bit % 8);
 
                 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
@@ -4117,12 +4390,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -4142,12 +4414,17 @@
 {
         ql_mbx_iocb_t   *pkt;
         int             rval;
         uint32_t        pkt_size;
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
+        if (ha->pha->task_daemon_flags & LOOP_DOWN) {
+                QL_PRINT_10(ha, "loop_down\n");
+                return (QL_FUNCTION_FAILED);
+        }
+
         pkt_size = sizeof (ql_mbx_iocb_t);
         pkt = kmem_zalloc(pkt_size, KM_SLEEP);
         if (pkt == NULL) {
                 EL(ha, "failed, kmem_zalloc\n");
                 return (QL_MEMORY_ALLOC_FAILED);
@@ -4157,10 +4434,11 @@
         pkt->vpm.entry_count = 1;
         pkt->vpm.command = cmd;
         pkt->vpm.vp_count = 1;
         pkt->vpm.first_vp_index = ha->vp_index;
         pkt->vpm.first_options = opt;
+        pkt->vpm.fcf_index = ha->fcoe_fcf_idx;
         bcopy(ha->loginparams.nport_ww_name.raw_wwn, pkt->vpm.first_port_name,
             8);
         bcopy(ha->loginparams.node_ww_name.raw_wwn, pkt->vpm.first_node_name,
             8);
 
@@ -4175,12 +4453,11 @@
 
         if (rval != QL_SUCCESS) {
                 EL(ha, "failed, rval = %xh\n", rval);
         } else {
                 /*EMPTY*/
-                QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
-                    ha->vp_index);
+                QL_PRINT_10(ha, "done\n");
         }
         return (rval);
 }
 
 /*
@@ -4196,38 +4473,42 @@
 int
 ql_vport_enable(ql_adapter_state_t *ha)
 {
         int     timer;
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         ha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
         TASK_DAEMON_LOCK(ha);
         ha->task_daemon_flags |= LOOP_DOWN;
         ha->task_daemon_flags &= ~(FC_STATE_CHANGE | STATE_ONLINE);
         TASK_DAEMON_UNLOCK(ha);
 
         ADAPTER_STATE_LOCK(ha);
         ha->flags |= VP_ENABLED;
+        ha->flags &= ~VP_ID_NOT_ACQUIRED;
         ADAPTER_STATE_UNLOCK(ha);
+        ha->fcoe_fcf_idx = 0;
 
         if (ql_vport_modify(ha, VPM_MODIFY_ENABLE, VPO_TARGET_MODE_DISABLED |
             VPO_INITIATOR_MODE_ENABLED | VPO_ENABLED) != QL_SUCCESS) {
-                QL_PRINT_2(CE_CONT, "(%d): failed to enable virtual port=%d\n",
-                    ha->instance, ha->vp_index);
+                QL_PRINT_2(ha, "failed to enable virtual port\n");
                 return (QL_FUNCTION_FAILED);
         }
         if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
                 /* Wait for loop to come up. */
                 for (timer = 0; timer < 3000 &&
                     !(ha->task_daemon_flags & STATE_ONLINE);
                     timer++) {
+                        if (ha->flags & VP_ID_NOT_ACQUIRED) {
+                                break;
+                        }
                         delay(1);
                 }
         }
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "done\n");
 
         return (QL_SUCCESS);
 }
 
 /*
@@ -4244,11 +4525,11 @@
 ql_adapter_state_t *
 ql_vport_create(ql_adapter_state_t *ha, uint8_t index)
 {
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         /* Inherit the parents data. */
         vha = kmem_alloc(sizeof (ql_adapter_state_t), KM_SLEEP);
 
         ADAPTER_STATE_LOCK(ha);
@@ -4270,11 +4551,11 @@
         vha->dev = kmem_zalloc(sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE,
             KM_SLEEP);
         vha->ub_array = kmem_zalloc(sizeof (*vha->ub_array) * QL_UB_LIMIT,
             KM_SLEEP);
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "done\n");
 
         return (vha);
 }
 
 /*
@@ -4290,11 +4571,11 @@
 void
 ql_vport_destroy(ql_adapter_state_t *ha)
 {
         ql_adapter_state_t      *vha;
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "started\n");
 
         /* Remove port from list. */
         ADAPTER_STATE_LOCK(ha);
         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
                 if (vha->vp_next == ha) {
@@ -4310,11 +4591,11 @@
         if (ha->dev != NULL) {
                 kmem_free(ha->dev, sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE);
         }
         kmem_free(ha, sizeof (ql_adapter_state_t));
 
-        QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
+        QL_PRINT_10(ha, "done\n");
 }
 
 /*
  * ql_mps_reset
  *      Reset MPS for FCoE functions.
@@ -4341,13 +4622,96 @@
                 }
         } while (!(data & BIT_0));
 
         if (ql_rd_risc_ram_word(ha, 0x7A15, &data) == QL_SUCCESS) {
                 dctl = (uint16_t)ql_pci_config_get16(ha, 0x54);
-                if ((data & 0xe0) != (dctl & 0xe0)) {
+                if ((data & 0xe0) < (dctl & 0xe0)) {
                         data &= 0xff1f;
                         data |= dctl & 0xe0;
                         (void) ql_wrt_risc_ram_word(ha, 0x7A15, data);
+                } else if ((data & 0xe0) != (dctl & 0xe0)) {
+                        data &= 0xff1f;
+                        data |= dctl & 0xe0;
+                        (void) ql_wrt_risc_ram_word(ha, 0x7A15, data);
                 }
         }
         (void) ql_wrt_risc_ram_word(ha, 0x7c00, 0);
+}
+
+/*
+ * ql_update_dev
+ *      Updates device status on loop reconfigure.
+ *
+ * Input:
+ *      ha:     adapter state pointer.
+ *      index:  list index of device data.
+ *
+ * Context:
+ *      Kernel context.
+ */
+static void
+ql_update_dev(ql_adapter_state_t *ha, uint32_t index)
+{
+        ql_link_t       *link;
+        ql_tgt_t        *tq;
+        int             rval;
+
+        QL_PRINT_3(ha, "started\n");
+
+        link = ha->dev[index].first;
+        while (link != NULL) {
+                tq = link->base_address;
+                link = link->next;
+
+                if (tq->loop_id & PORT_LOST_ID &&
+                    !(tq->flags & (TQF_INITIATOR_DEVICE | TQF_FABRIC_DEVICE))) {
+
+                        tq->loop_id &= ~PORT_LOST_ID;
+
+                        if (VALID_DEVICE_ID(ha, tq->loop_id)) {
+                                /* implicit logo due to fw issue */
+                                rval = ql_get_port_database(ha, tq, PDF_NONE);
+
+                                if (rval == QL_NOT_LOGGED_IN) {
+                                        if (tq->master_state ==
+                                            PD_STATE_PORT_UNAVAILABLE) {
+                                                (void) ql_logout_fabric_port(
+                                                    ha, tq);
+                                                tq->loop_id = PORT_NO_LOOP_ID;
+                                        }
+                                } else if (rval == QL_SUCCESS) {
+                                        tq->loop_id = PORT_NO_LOOP_ID;
+                                }
+                        }
+                } else if (ha->topology & QL_NL_PORT &&
+                    tq->flags & TQF_FABRIC_DEVICE) {
+
+                        tq->loop_id &= ~PORT_LOST_ID;
+
+                        if (VALID_DEVICE_ID(ha, tq->loop_id)) {
+                                /* implicit logo due to fw issue */
+                                rval = ql_get_port_database(ha, tq, PDF_NONE);
+
+                                if (rval == QL_NOT_LOGGED_IN) {
+                                        if (tq->master_state ==
+                                            PD_STATE_PORT_UNAVAILABLE) {
+                                                (void) ql_logout_fabric_port(
+                                                    ha, tq);
+                                                /*
+                                                 * fabric to AL topo change
+                                                 */
+                                                tq->loop_id = PORT_NO_LOOP_ID;
+                                        }
+                                } else if (rval == QL_SUCCESS) {
+                                        /*
+                                         * Normally this is 7fe,
+                                         * Don't issue logo, it causes
+                                         * logo in single tgt AL.
+                                         */
+                                        tq->loop_id = PORT_NO_LOOP_ID;
+                                }
+                        }
+                }
+        }
+
+        QL_PRINT_3(ha, "done\n");
 }