1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* Copyright 2010 QLogic Corporation */
  23 
  24 /*
  25  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 
  28 #pragma ident   "Copyright 2010 QLogic Corporation; ql_init.c"
  29 
  30 /*
  31  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  32  *
  33  * ***********************************************************************
  34  * *                                                                    **
  35  * *                            NOTICE                                  **
  36  * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
  37  * *                    ALL RIGHTS RESERVED                             **
  38  * *                                                                    **
  39  * ***********************************************************************
  40  *
  41  */
  42 
  43 #include <ql_apps.h>
  44 #include <ql_api.h>
  45 #include <ql_debug.h>
  46 #include <ql_init.h>
  47 #include <ql_iocb.h>
  48 #include <ql_isr.h>
  49 #include <ql_mbx.h>
  50 #include <ql_nx.h>
  51 #include <ql_xioctl.h>
  52 
  53 /*
  54  * Local data
  55  */
  56 
  57 /*
  58  * Local prototypes
  59  */
  60 static uint16_t ql_nvram_request(ql_adapter_state_t *, uint32_t);
  61 static int ql_nvram_24xx_config(ql_adapter_state_t *);
  62 static void ql_23_properties(ql_adapter_state_t *, nvram_t *);
  63 static void ql_24xx_properties(ql_adapter_state_t *, nvram_24xx_t *);
  64 static int ql_check_isp_firmware(ql_adapter_state_t *);
  65 static int ql_chip_diag(ql_adapter_state_t *);
  66 static int ql_load_flash_fw(ql_adapter_state_t *);
  67 static int ql_configure_loop(ql_adapter_state_t *);
  68 static int ql_configure_hba(ql_adapter_state_t *);
  69 static int ql_configure_fabric(ql_adapter_state_t *);
  70 static int ql_configure_device_d_id(ql_adapter_state_t *);
  71 static void ql_set_max_read_req(ql_adapter_state_t *);
  72 static void ql_configure_n_port_info(ql_adapter_state_t *);
  73 static void ql_clear_mcp(ql_adapter_state_t *);
  74 static void ql_mps_reset(ql_adapter_state_t *);
  75 
  76 /*
  77  * ql_initialize_adapter
  78  *      Initialize board.
  79  *
  80  * Input:
  81  *      ha = adapter state pointer.
  82  *
  83  * Returns:
  84  *      ql local function return status code.
  85  *
  86  * Context:
  87  *      Kernel context.
  88  */
  89 int
  90 ql_initialize_adapter(ql_adapter_state_t *ha)
  91 {
  92         int                     rval;
  93         class_svc_param_t       *class3_param;
  94         caddr_t                 msg;
  95         la_els_logi_t           *els = &ha->loginparams;
  96         int                     retries = 5;
  97 
  98         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
  99 
 100         do {
 101                 /* Clear adapter flags. */
 102                 TASK_DAEMON_LOCK(ha);
 103                 ha->task_daemon_flags &= TASK_DAEMON_STOP_FLG |
 104                     TASK_DAEMON_SLEEPING_FLG | TASK_DAEMON_ALIVE_FLG |
 105                     TASK_DAEMON_IDLE_CHK_FLG;
 106                 ha->task_daemon_flags |= LOOP_DOWN;
 107                 TASK_DAEMON_UNLOCK(ha);
 108 
 109                 ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
 110                 ADAPTER_STATE_LOCK(ha);
 111                 ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
 112                 ha->flags &= ~ONLINE;
 113                 ADAPTER_STATE_UNLOCK(ha);
 114 
 115                 ha->state = FC_STATE_OFFLINE;
 116                 msg = "Loop OFFLINE";
 117 
 118                 rval = ql_pci_sbus_config(ha);
 119                 if (rval != QL_SUCCESS) {
 120                         TASK_DAEMON_LOCK(ha);
 121                         if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
 122                                 EL(ha, "ql_pci_sbus_cfg, isp_abort_needed\n");
 123                                 ha->task_daemon_flags |= ISP_ABORT_NEEDED;
 124                         }
 125                         TASK_DAEMON_UNLOCK(ha);
 126                         continue;
 127                 }
 128 
 129                 (void) ql_setup_fcache(ha);
 130 
 131                 /* Reset ISP chip. */
 132                 ql_reset_chip(ha);
 133 
 134                 /* Get NVRAM configuration if needed. */
 135                 if (ha->init_ctrl_blk.cb.version == 0) {
 136                         (void) ql_nvram_config(ha);
 137                 }
 138 
 139                 /* Set login parameters. */
 140                 if (CFG_IST(ha, CFG_CTRL_24258081)) {
 141                         els->common_service.rx_bufsize = CHAR_TO_SHORT(
 142                             ha->init_ctrl_blk.cb24.max_frame_length[0],
 143                             ha->init_ctrl_blk.cb24.max_frame_length[1]);
 144                         bcopy((void *)&ha->init_ctrl_blk.cb24.port_name[0],
 145                             (void *)&els->nport_ww_name.raw_wwn[0], 8);
 146                         bcopy((void *)&ha->init_ctrl_blk.cb24.node_name[0],
 147                             (void *)&els->node_ww_name.raw_wwn[0], 8);
 148                 } else {
 149                         els->common_service.rx_bufsize = CHAR_TO_SHORT(
 150                             ha->init_ctrl_blk.cb.max_frame_length[0],
 151                             ha->init_ctrl_blk.cb.max_frame_length[1]);
 152                         bcopy((void *)&ha->init_ctrl_blk.cb.port_name[0],
 153                             (void *)&els->nport_ww_name.raw_wwn[0], 8);
 154                         bcopy((void *)&ha->init_ctrl_blk.cb.node_name[0],
 155                             (void *)&els->node_ww_name.raw_wwn[0], 8);
 156                 }
 157                 bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
 158                     strlen(QL_VERSION));
 159 
 160                 /* Determine which RISC code to use. */
 161                 if ((rval = ql_check_isp_firmware(ha)) != QL_SUCCESS) {
 162                         if ((rval = ql_chip_diag(ha)) == QL_SUCCESS) {
 163                                 rval = ql_load_isp_firmware(ha);
 164                         }
 165                 }
 166 
 167                 if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
 168                     QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS) {
 169 
 170                         (void) ql_fw_ready(ha, ha->fwwait);
 171 
 172                         if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
 173                             ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
 174                                 if (ha->topology & QL_LOOP_CONNECTION) {
 175                                         ha->state = ha->state | FC_STATE_LOOP;
 176                                         msg = "Loop ONLINE";
 177                                         ha->task_daemon_flags |= STATE_ONLINE;
 178                                 } else if (ha->topology & QL_P2P_CONNECTION) {
 179                                         ha->state = ha->state |
 180                                             FC_STATE_ONLINE;
 181                                         msg = "Link ONLINE";
 182                                         ha->task_daemon_flags |= STATE_ONLINE;
 183                                 } else {
 184                                         msg = "Unknown Link state";
 185                                 }
 186                         }
 187                 } else {
 188                         TASK_DAEMON_LOCK(ha);
 189                         if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
 190                                 EL(ha, "failed, isp_abort_needed\n");
 191                                 ha->task_daemon_flags |= ISP_ABORT_NEEDED |
 192                                     LOOP_DOWN;
 193                         }
 194                         TASK_DAEMON_UNLOCK(ha);
 195                 }
 196 
 197         } while (retries-- != 0 && ha->task_daemon_flags & ISP_ABORT_NEEDED);
 198 
 199         cmn_err(CE_NOTE, "!Qlogic %s(%d): %s", QL_NAME, ha->instance, msg);
 200 
 201         /* Enable ISP interrupts and login parameters. */
 202         if (CFG_IST(ha, CFG_CTRL_8021)) {
 203                 ql_8021_enable_intrs(ha);
 204         } else if (CFG_IST(ha, CFG_CTRL_242581)) {
 205                 WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
 206         } else {
 207                 WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
 208         }
 209 
 210         ADAPTER_STATE_LOCK(ha);
 211         ha->flags |= (INTERRUPTS_ENABLED | ONLINE);
 212         ADAPTER_STATE_UNLOCK(ha);
 213 
 214         ha->task_daemon_flags &= ~(FC_STATE_CHANGE | RESET_MARKER_NEEDED |
 215             COMMAND_WAIT_NEEDED);
 216 
 217         /*
 218          * Setup login parameters.
 219          */
 220         els->common_service.fcph_version = 0x2006;
 221         els->common_service.btob_credit = 3;
 222         els->common_service.cmn_features = 0x8800;
 223         els->common_service.conc_sequences = 0xff;
 224         els->common_service.relative_offset = 3;
 225         els->common_service.e_d_tov = 0x07d0;
 226 
 227         class3_param = (class_svc_param_t *)&els->class_3;
 228         class3_param->class_valid_svc_opt = 0x8800;
 229         class3_param->rcv_data_size = els->common_service.rx_bufsize;
 230         class3_param->conc_sequences = 0xff;
 231 
 232         if (rval != QL_SUCCESS) {
 233                 EL(ha, "failed, rval = %xh\n", rval);
 234         } else {
 235                 /*EMPTY*/
 236                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
 237         }
 238         return (rval);
 239 }
 240 
 241 /*
 242  * ql_pci_sbus_config
 243  *      Setup device PCI/SBUS configuration registers.
 244  *
 245  * Input:
 246  *      ha = adapter state pointer.
 247  *
 248  * Returns:
 249  *      ql local function return status code.
 250  *
 251  * Context:
 252  *      Kernel context.
 253  */
 254 int
 255 ql_pci_sbus_config(ql_adapter_state_t *ha)
 256 {
 257         uint32_t        timer;
 258         uint16_t        cmd, w16;
 259 
 260         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
 261 
 262         if (CFG_IST(ha, CFG_SBUS_CARD)) {
 263                 w16 = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
 264                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_REVISION));
 265                 EL(ha, "FPGA rev is %d.%d", (w16 & 0xf0) >> 4,
 266                     w16 & 0xf);
 267         } else {
 268                 /*
 269                  * we want to respect framework's setting of PCI
 270                  * configuration space command register and also
 271                  * want to make sure that all bits of interest to us
 272                  * are properly set in command register.
 273                  */
 274                 cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
 275                 cmd = (uint16_t)(cmd | PCI_COMM_IO | PCI_COMM_MAE |
 276                     PCI_COMM_ME | PCI_COMM_MEMWR_INVAL |
 277                     PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
 278 
 279                 /*
 280                  * If this is a 2300 card and not 2312, reset the
 281                  * MEMWR_INVAL due to a bug in the 2300. Unfortunately, the
 282                  * 2310 also reports itself as a 2300 so we need to get the
 283                  * fb revision level -- a 6 indicates it really is a 2300 and
 284                  * not a 2310.
 285                  */
 286 
 287                 if (ha->device_id == 0x2300) {
 288                         /* Pause RISC. */
 289                         WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
 290                         for (timer = 0; timer < 30000; timer++) {
 291                                 if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) !=
 292                                     0) {
 293                                         break;
 294                                 } else {
 295                                         drv_usecwait(MILLISEC);
 296                                 }
 297                         }
 298 
 299                         /* Select FPM registers. */
 300                         WRT16_IO_REG(ha, ctrl_status, 0x20);
 301 
 302                         /* Get the fb rev level */
 303                         if (RD16_IO_REG(ha, fb_cmd) == 6) {
 304                                 cmd = (uint16_t)(cmd & ~PCI_COMM_MEMWR_INVAL);
 305                         }
 306 
 307                         /* Deselect FPM registers. */
 308                         WRT16_IO_REG(ha, ctrl_status, 0x0);
 309 
 310                         /* Release RISC module. */
 311                         WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
 312                         for (timer = 0; timer < 30000; timer++) {
 313                                 if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) ==
 314                                     0) {
 315                                         break;
 316                                 } else {
 317                                         drv_usecwait(MILLISEC);
 318                                 }
 319                         }
 320                 } else if (ha->device_id == 0x2312) {
 321                         /*
 322                          * cPCI ISP2312 specific code to service function 1
 323                          * hot-swap registers.
 324                          */
 325                         if ((RD16_IO_REG(ha, ctrl_status) & ISP_FUNC_NUM_MASK)
 326                             != 0) {
 327                                 ql_pci_config_put8(ha, 0x66, 0xc2);
 328                         }
 329                 }
 330 
 331                 if (!(CFG_IST(ha, CFG_CTRL_8021)) &&
 332                     ha->pci_max_read_req != 0) {
 333                         ql_set_max_read_req(ha);
 334                 }
 335 
 336                 ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
 337 
 338                 /* Set cache line register. */
 339                 ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ, 0x10);
 340 
 341                 /* Set latency register. */
 342                 ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 0x40);
 343 
 344                 /* Reset expansion ROM address decode enable. */
 345                 w16 = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_ROM);
 346                 w16 = (uint16_t)(w16 & ~BIT_0);
 347                 ql_pci_config_put16(ha, PCI_CONF_ROM, w16);
 348         }
 349 
 350         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
 351 
 352         return (QL_SUCCESS);
 353 }
 354 
 355 /*
 356  * Set the PCI max read request value.
 357  *
 358  * Input:
 359  *      ha:             adapter state pointer.
 360  *
 361  * Output:
 362  *      none.
 363  *
 364  * Returns:
 365  *
 366  * Context:
 367  *      Kernel context.
 368  */
 369 
 370 static void
 371 ql_set_max_read_req(ql_adapter_state_t *ha)
 372 {
 373         uint16_t        read_req, w16;
 374         uint16_t        tmp = ha->pci_max_read_req;
 375 
 376         if ((ha->device_id == 0x2422) ||
 377             ((ha->device_id & 0xff00) == 0x2300)) {
 378                 /* check for vaild override value */
 379                 if (tmp == 512 || tmp == 1024 || tmp == 2048 ||
 380                     tmp == 4096) {
 381                         /* shift away the don't cares */
 382                         tmp = (uint16_t)(tmp >> 10);
 383                         /* convert bit pos to request value */
 384                         for (read_req = 0; tmp != 0; read_req++) {
 385                                 tmp = (uint16_t)(tmp >> 1);
 386                         }
 387                         w16 = (uint16_t)ql_pci_config_get16(ha, 0x4e);
 388                         w16 = (uint16_t)(w16 & ~(BIT_3 & BIT_2));
 389                         w16 = (uint16_t)(w16 | (read_req << 2));
 390                         ql_pci_config_put16(ha, 0x4e, w16);
 391                 } else {
 392                         EL(ha, "invalid parameter value for "
 393                             "'pci-max-read-request': %d; using system "
 394                             "default\n", tmp);
 395                 }
 396         } else if ((ha->device_id == 0x2432) || ((ha->device_id & 0xff00) ==
 397             0x2500) || (ha->device_id == 0x8432)) {
 398                 /* check for vaild override value */
 399                 if (tmp == 128 || tmp == 256 || tmp == 512 ||
 400                     tmp == 1024 || tmp == 2048 || tmp == 4096) {
 401                         /* shift away the don't cares */
 402                         tmp = (uint16_t)(tmp >> 8);
 403                         /* convert bit pos to request value */
 404                         for (read_req = 0; tmp != 0; read_req++) {
 405                                 tmp = (uint16_t)(tmp >> 1);
 406                         }
 407                         w16 = (uint16_t)ql_pci_config_get16(ha, 0x54);
 408                         w16 = (uint16_t)(w16 & ~(BIT_14 | BIT_13 |
 409                             BIT_12));
 410                         w16 = (uint16_t)(w16 | (read_req << 12));
 411                         ql_pci_config_put16(ha, 0x54, w16);
 412                 } else {
 413                         EL(ha, "invalid parameter value for "
 414                             "'pci-max-read-request': %d; using system "
 415                             "default\n", tmp);
 416                 }
 417         }
 418 }
 419 
 420 /*
 421  * NVRAM configuration.
 422  *
 423  * Input:
 424  *      ha:             adapter state pointer.
 425  *      ha->hba_buf = request and response rings
 426  *
 427  * Output:
 428  *      ha->init_ctrl_blk = initialization control block
 429  *      host adapters parameters in host adapter block
 430  *
 431  * Returns:
 432  *      ql local function return status code.
 433  *
 434  * Context:
 435  *      Kernel context.
 436  */
 437 int
 438 ql_nvram_config(ql_adapter_state_t *ha)
 439 {
 440         uint32_t        cnt;
 441         caddr_t         dptr1, dptr2;
 442         ql_init_cb_t    *icb = &ha->init_ctrl_blk.cb;
 443         ql_ip_init_cb_t *ip_icb = &ha->ip_init_ctrl_blk.cb;
 444         nvram_t         *nv = (nvram_t *)ha->request_ring_bp;
 445         uint16_t        *wptr = (uint16_t *)ha->request_ring_bp;
 446         uint8_t         chksum = 0;
 447         int             rval;
 448         int             idpromlen;
 449         char            idprombuf[32];
 450         uint32_t        start_addr;
 451 
 452         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
 453 
 454         if (CFG_IST(ha, CFG_CTRL_24258081)) {
 455                 return (ql_nvram_24xx_config(ha));
 456         }
 457 
 458         start_addr = 0;
 459         if ((rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA)) ==
 460             QL_SUCCESS) {
 461                 /* Verify valid NVRAM checksum. */
 462                 for (cnt = 0; cnt < sizeof (nvram_t)/2; cnt++) {
 463                         *wptr = (uint16_t)ql_get_nvram_word(ha,
 464                             (uint32_t)(cnt + start_addr));
 465                         chksum = (uint8_t)(chksum + (uint8_t)*wptr);
 466                         chksum = (uint8_t)(chksum + (uint8_t)(*wptr >> 8));
 467                         wptr++;
 468                 }
 469                 ql_release_nvram(ha);
 470         }
 471 
 472         /* Bad NVRAM data, set defaults parameters. */
 473         if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
 474             nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
 475             nv->nvram_version < 1) {
 476 
 477                 EL(ha, "failed, rval=%xh, checksum=%xh, "
 478                     "id=%02x%02x%02x%02xh, flsz=%xh, pciconfvid=%xh, "
 479                     "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
 480                     nv->id[2], nv->id[3], ha->xioctl->fdesc.flash_size,
 481                     ha->subven_id, nv->nvram_version);
 482 
 483                 /* Don't print nvram message if it's an on-board 2200 */
 484                 if (!((CFG_IST(ha, CFG_CTRL_2200)) &&
 485                     (ha->xioctl->fdesc.flash_size == 0))) {
 486                         cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed,"
 487                             " using driver defaults.", QL_NAME, ha->instance);
 488                 }
 489 
 490                 /* Reset NVRAM data. */
 491                 bzero((void *)nv, sizeof (nvram_t));
 492 
 493                 /*
 494                  * Set default initialization control block.
 495                  */
 496                 nv->parameter_block_version = ICB_VERSION;
 497                 nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1;
 498                 nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2;
 499 
 500                 nv->max_frame_length[1] = 4;
 501 
 502                 /*
 503                  * Allow 2048 byte frames for 2300
 504                  */
 505                 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
 506                         nv->max_frame_length[1] = 8;
 507                 }
 508                 nv->max_iocb_allocation[1] = 1;
 509                 nv->execution_throttle[0] = 16;
 510                 nv->login_retry_count = 8;
 511 
 512                 idpromlen = 32;
 513 
 514                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
 515                 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
 516                     DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
 517                     &idpromlen) != DDI_PROP_SUCCESS) {
 518 
 519                         QL_PRINT_3(CE_CONT, "(%d): Unable to read idprom "
 520                             "property\n", ha->instance);
 521                         cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
 522                             "property", QL_NAME, ha->instance);
 523 
 524                         nv->port_name[2] = 33;
 525                         nv->port_name[3] = 224;
 526                         nv->port_name[4] = 139;
 527                         nv->port_name[7] = (uint8_t)
 528                             (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
 529                 } else {
 530 
 531                         nv->port_name[2] = idprombuf[2];
 532                         nv->port_name[3] = idprombuf[3];
 533                         nv->port_name[4] = idprombuf[4];
 534                         nv->port_name[5] = idprombuf[5];
 535                         nv->port_name[6] = idprombuf[6];
 536                         nv->port_name[7] = idprombuf[7];
 537                         nv->port_name[0] = (uint8_t)
 538                             (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
 539                 }
 540 
 541                 /* Don't print nvram message if it's an on-board 2200 */
 542                 if (!(CFG_IST(ha, CFG_CTRL_2200)) &&
 543                     (ha->xioctl->fdesc.flash_size == 0)) {
 544                         cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using"
 545                             " default HBA parameters and temporary WWPN:"
 546                             " %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
 547                             ha->instance, nv->port_name[0], nv->port_name[1],
 548                             nv->port_name[2], nv->port_name[3],
 549                             nv->port_name[4], nv->port_name[5],
 550                             nv->port_name[6], nv->port_name[7]);
 551                 }
 552 
 553                 nv->login_timeout = 4;
 554 
 555                 /* Set default connection options for the 23xx to 2 */
 556                 if (!(CFG_IST(ha, CFG_CTRL_2200))) {
 557                         nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
 558                             BIT_5);
 559                 }
 560 
 561                 /*
 562                  * Set default host adapter parameters
 563                  */
 564                 nv->host_p[0] = BIT_1;
 565                 nv->host_p[1] = BIT_2;
 566                 nv->reset_delay = 5;
 567                 nv->port_down_retry_count = 8;
 568                 nv->maximum_luns_per_target[0] = 8;
 569 
 570                 rval = QL_FUNCTION_FAILED;
 571         }
 572 
 573         /* Check for adapter node name (big endian). */
 574         for (cnt = 0; cnt < 8; cnt++) {
 575                 if (nv->node_name[cnt] != 0) {
 576                         break;
 577                 }
 578         }
 579 
 580         /* Copy port name if no node name (big endian). */
 581         if (cnt == 8) {
 582                 bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
 583                 nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
 584                 nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
 585         }
 586 
 587         /* Reset initialization control blocks. */
 588         bzero((void *)icb, sizeof (ql_init_cb_t));
 589 
 590         /* Get driver properties. */
 591         ql_23_properties(ha, nv);
 592 
 593         cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
 594             "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
 595             QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
 596             nv->port_name[2], nv->port_name[3], nv->port_name[4],
 597             nv->port_name[5], nv->port_name[6], nv->port_name[7],
 598             nv->node_name[0], nv->node_name[1], nv->node_name[2],
 599             nv->node_name[3], nv->node_name[4], nv->node_name[5],
 600             nv->node_name[6], nv->node_name[7]);
 601 
 602         /*
 603          * Copy over NVRAM RISC parameter block
 604          * to initialization control block.
 605          */
 606         dptr1 = (caddr_t)icb;
 607         dptr2 = (caddr_t)&nv->parameter_block_version;
 608         cnt = (uint32_t)((uintptr_t)&icb->request_q_outpointer[0] -
 609             (uintptr_t)&icb->version);
 610         while (cnt-- != 0) {
 611                 *dptr1++ = *dptr2++;
 612         }
 613 
 614         /* Copy 2nd half. */
 615         dptr1 = (caddr_t)&icb->add_fw_opt[0];
 616         cnt = (uint32_t)((uintptr_t)&icb->reserved_3[0] -
 617             (uintptr_t)&icb->add_fw_opt[0]);
 618 
 619         while (cnt-- != 0) {
 620                 *dptr1++ = *dptr2++;
 621         }
 622 
 623         /*
 624          * Setup driver firmware options.
 625          */
 626         icb->firmware_options[0] = (uint8_t)
 627             (icb->firmware_options[0] | BIT_6 | BIT_1);
 628 
 629         /*
 630          * There is no use enabling fast post for SBUS or 2300
 631          * Always enable 64bit addressing, except SBUS cards.
 632          */
 633         ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
 634         if (CFG_IST(ha, (CFG_SBUS_CARD | CFG_CTRL_2300 | CFG_CTRL_6322))) {
 635                 icb->firmware_options[0] = (uint8_t)
 636                     (icb->firmware_options[0] & ~BIT_3);
 637                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
 638                         icb->special_options[0] = (uint8_t)
 639                             (icb->special_options[0] | BIT_5);
 640                         ha->cfg_flags &= ~CFG_ENABLE_64BIT_ADDRESSING;
 641                 }
 642         } else {
 643                 icb->firmware_options[0] = (uint8_t)
 644                     (icb->firmware_options[0] | BIT_3);
 645         }
 646         /* RIO and ZIO not supported. */
 647         icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] &
 648             ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
 649 
 650         icb->firmware_options[1] = (uint8_t)(icb->firmware_options[1] |
 651             BIT_7 | BIT_6 | BIT_5 | BIT_2 | BIT_0);
 652         icb->firmware_options[0] = (uint8_t)
 653             (icb->firmware_options[0] & ~(BIT_5 | BIT_4));
 654         icb->firmware_options[1] = (uint8_t)
 655             (icb->firmware_options[1] & ~BIT_4);
 656 
 657         icb->add_fw_opt[1] = (uint8_t)(icb->add_fw_opt[1] & ~(BIT_5 | BIT_4));
 658         icb->special_options[0] = (uint8_t)(icb->special_options[0] | BIT_1);
 659 
 660         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
 661                 if ((icb->special_options[1] & 0x20) == 0) {
 662                         EL(ha, "50 ohm is not set\n");
 663                 }
 664         }
 665         icb->execution_throttle[0] = 0xff;
 666         icb->execution_throttle[1] = 0xff;
 667 
 668         if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
 669                 icb->firmware_options[1] = (uint8_t)
 670                     (icb->firmware_options[1] | BIT_7 | BIT_6);
 671                 icb->add_fw_opt[1] = (uint8_t)
 672                     (icb->add_fw_opt[1] | BIT_5 | BIT_4);
 673         }
 674 
 675         /*
 676          * Set host adapter parameters
 677          */
 678         ADAPTER_STATE_LOCK(ha);
 679         ha->nvram_version = nv->nvram_version;
 680         ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
 681             nv->adapter_features[1]);
 682 
 683         nv->host_p[0] & BIT_4 ? (ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD) :
 684             (ha->cfg_flags &= ~CFG_DISABLE_RISC_CODE_LOAD);
 685         nv->host_p[0] & BIT_5 ? (ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1) :
 686             (ha->cfg_flags &= ~CFG_SET_CACHE_LINE_SIZE_1);
 687 
 688         nv->host_p[1] & BIT_1 ? (ha->cfg_flags |= CFG_ENABLE_LIP_RESET) :
 689             (ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET);
 690         nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
 691             (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
 692         nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
 693             (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
 694 
 695         nv->adapter_features[0] & BIT_3 ?
 696             (ha->cfg_flags |= CFG_MULTI_CHIP_ADAPTER) :
 697             (ha->cfg_flags &= ~CFG_MULTI_CHIP_ADAPTER);
 698 
 699         ADAPTER_STATE_UNLOCK(ha);
 700 
 701         ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
 702             nv->execution_throttle[1]);
 703         ha->loop_reset_delay = nv->reset_delay;
 704         ha->port_down_retry_count = nv->port_down_retry_count;
 705         ha->r_a_tov = (uint16_t)(icb->login_timeout < R_A_TOV_DEFAULT ?
 706             R_A_TOV_DEFAULT : icb->login_timeout);
 707         ha->maximum_luns_per_target = CHAR_TO_SHORT(
 708             nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
 709         if (ha->maximum_luns_per_target == 0) {
 710                 ha->maximum_luns_per_target++;
 711         }
 712 
 713         /*
 714          * Setup ring parameters in initialization control block
 715          */
 716         cnt = REQUEST_ENTRY_CNT;
 717         icb->request_q_length[0] = LSB(cnt);
 718         icb->request_q_length[1] = MSB(cnt);
 719         cnt = RESPONSE_ENTRY_CNT;
 720         icb->response_q_length[0] = LSB(cnt);
 721         icb->response_q_length[1] = MSB(cnt);
 722 
 723         icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
 724         icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
 725         icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
 726         icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
 727         icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
 728         icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
 729         icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
 730         icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
 731 
 732         icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
 733         icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
 734         icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
 735         icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
 736         icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
 737         icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
 738         icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
 739         icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
 740 
 741         /*
 742          * Setup IP initialization control block
 743          */
 744         ip_icb->version = IP_ICB_VERSION;
 745 
 746         if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
 747                 ip_icb->ip_firmware_options[0] = (uint8_t)
 748                     (ip_icb->ip_firmware_options[0] | BIT_2 | BIT_0);
 749         } else {
 750                 ip_icb->ip_firmware_options[0] = (uint8_t)
 751                     (ip_icb->ip_firmware_options[0] | BIT_2);
 752         }
 753 
 754         cnt = RCVBUF_CONTAINER_CNT;
 755         ip_icb->queue_size[0] = LSB(cnt);
 756         ip_icb->queue_size[1] = MSB(cnt);
 757 
 758         ip_icb->queue_address[0] = LSB(LSW(LSD(ha->rcvbuf_dvma)));
 759         ip_icb->queue_address[1] = MSB(LSW(LSD(ha->rcvbuf_dvma)));
 760         ip_icb->queue_address[2] = LSB(MSW(LSD(ha->rcvbuf_dvma)));
 761         ip_icb->queue_address[3] = MSB(MSW(LSD(ha->rcvbuf_dvma)));
 762         ip_icb->queue_address[4] = LSB(LSW(MSD(ha->rcvbuf_dvma)));
 763         ip_icb->queue_address[5] = MSB(LSW(MSD(ha->rcvbuf_dvma)));
 764         ip_icb->queue_address[6] = LSB(MSW(MSD(ha->rcvbuf_dvma)));
 765         ip_icb->queue_address[7] = MSB(MSW(MSD(ha->rcvbuf_dvma)));
 766 
 767         if (rval != QL_SUCCESS) {
 768                 EL(ha, "failed, rval = %xh\n", rval);
 769         } else {
 770                 /*EMPTY*/
 771                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
 772         }
 773         return (rval);
 774 }
 775 
 776 /*
 777  * Get NVRAM data word
 778  *      Calculates word position in NVRAM and calls request routine to
 779  *      get the word from NVRAM.
 780  *
 781  * Input:
 782  *      ha = adapter state pointer.
 783  *      address = NVRAM word address.
 784  *
 785  * Returns:
 786  *      data word.
 787  *
 788  * Context:
 789  *      Kernel context.
 790  */
 791 uint16_t
 792 ql_get_nvram_word(ql_adapter_state_t *ha, uint32_t address)
 793 {
 794         uint32_t        nv_cmd;
 795         uint16_t        rval;
 796 
 797         QL_PRINT_4(CE_CONT, "(%d): started\n", ha->instance);
 798 
 799         nv_cmd = address << 16;
 800         nv_cmd = nv_cmd | NV_READ_OP;
 801 
 802         rval = (uint16_t)ql_nvram_request(ha, nv_cmd);
 803 
 804         QL_PRINT_4(CE_CONT, "(%d): NVRAM data = %xh\n", ha->instance, rval);
 805 
 806         return (rval);
 807 }
 808 
 809 /*
 810  * NVRAM request
 811  *      Sends read command to NVRAM and gets data from NVRAM.
 812  *
 813  * Input:
 814  *      ha = adapter state pointer.
 815  *      nv_cmd = Bit 26= start bit
 816  *      Bit 25, 24 = opcode
 817  *      Bit 23-16 = address
 818  *      Bit 15-0 = write data
 819  *
 820  * Returns:
 821  *      data word.
 822  *
 823  * Context:
 824  *      Kernel context.
 825  */
 826 static uint16_t
 827 ql_nvram_request(ql_adapter_state_t *ha, uint32_t nv_cmd)
 828 {
 829         uint8_t         cnt;
 830         uint16_t        reg_data;
 831         uint16_t        data = 0;
 832 
 833         /* Send command to NVRAM. */
 834 
 835         nv_cmd <<= 5;
 836         for (cnt = 0; cnt < 11; cnt++) {
 837                 if (nv_cmd & BIT_31) {
 838                         ql_nv_write(ha, NV_DATA_OUT);
 839                 } else {
 840                         ql_nv_write(ha, 0);
 841                 }
 842                 nv_cmd <<= 1;
 843         }
 844 
 845         /* Read data from NVRAM. */
 846 
 847         for (cnt = 0; cnt < 16; cnt++) {
 848                 WRT16_IO_REG(ha, nvram, NV_SELECT+NV_CLOCK);
 849                 ql_nv_delay();
 850                 data <<= 1;
 851                 reg_data = RD16_IO_REG(ha, nvram);
 852                 if (reg_data & NV_DATA_IN) {
 853                         data = (uint16_t)(data | BIT_0);
 854                 }
 855                 WRT16_IO_REG(ha, nvram, NV_SELECT);
 856                 ql_nv_delay();
 857         }
 858 
 859         /* Deselect chip. */
 860 
 861         WRT16_IO_REG(ha, nvram, NV_DESELECT);
 862         ql_nv_delay();
 863 
 864         return (data);
 865 }
 866 
 867 void
 868 ql_nv_write(ql_adapter_state_t *ha, uint16_t data)
 869 {
 870         WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
 871         ql_nv_delay();
 872         WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT | NV_CLOCK));
 873         ql_nv_delay();
 874         WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
 875         ql_nv_delay();
 876 }
 877 
 878 void
 879 ql_nv_delay(void)
 880 {
 881         drv_usecwait(NV_DELAY_COUNT);
 882 }
 883 
 884 /*
 885  * ql_nvram_24xx_config
 886  *      ISP2400 nvram.
 887  *
 888  * Input:
 889  *      ha:             adapter state pointer.
 890  *      ha->hba_buf = request and response rings
 891  *
 892  * Output:
 893  *      ha->init_ctrl_blk = initialization control block
 894  *      host adapters parameters in host adapter block
 895  *
 896  * Returns:
 897  *      ql local function return status code.
 898  *
 899  * Context:
 900  *      Kernel context.
 901  */
 902 int
 903 ql_nvram_24xx_config(ql_adapter_state_t *ha)
 904 {
 905         uint32_t                index, addr, chksum, saved_chksum;
 906         uint32_t                *longptr;
 907         nvram_24xx_t            nvram;
 908         int                     idpromlen;
 909         char                    idprombuf[32];
 910         caddr_t                 src, dst;
 911         uint16_t                w1;
 912         int                     rval;
 913         nvram_24xx_t            *nv = (nvram_24xx_t *)&nvram;
 914         ql_init_24xx_cb_t       *icb =
 915             (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
 916         ql_ip_init_24xx_cb_t    *ip_icb = &ha->ip_init_ctrl_blk.cb24;
 917 
 918         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
 919 
 920         if ((rval = ql_lock_nvram(ha, &addr, LNF_NVRAM_DATA)) == QL_SUCCESS) {
 921 
 922                 /* Get NVRAM data and calculate checksum. */
 923                 longptr = (uint32_t *)nv;
 924                 chksum = saved_chksum = 0;
 925                 for (index = 0; index < sizeof (nvram_24xx_t) / 4; index++) {
 926                         rval = ql_24xx_read_flash(ha, addr++, longptr);
 927                         if (rval != QL_SUCCESS) {
 928                                 EL(ha, "24xx_read_flash failed=%xh\n", rval);
 929                                 break;
 930                         }
 931                         saved_chksum = chksum;
 932                         chksum += *longptr;
 933                         LITTLE_ENDIAN_32(longptr);
 934                         longptr++;
 935                 }
 936 
 937                 ql_release_nvram(ha);
 938         }
 939 
 940         /* Bad NVRAM data, set defaults parameters. */
 941         if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
 942             nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
 943             (nv->nvram_version[0] | nv->nvram_version[1]) == 0) {
 944 
 945                 cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed, using "
 946                     "driver defaults.", QL_NAME, ha->instance);
 947 
 948                 EL(ha, "failed, rval=%xh, checksum=%xh, id=%c%c%c%c, "
 949                     "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
 950                     nv->id[2], nv->id[3], CHAR_TO_SHORT(nv->nvram_version[0],
 951                     nv->nvram_version[1]));
 952 
 953                 saved_chksum = ~saved_chksum + 1;
 954 
 955                 (void) ql_flash_errlog(ha, FLASH_ERRLOG_NVRAM_CHKSUM_ERR, 0,
 956                     MSW(saved_chksum), LSW(saved_chksum));
 957 
 958                 /* Reset NVRAM data. */
 959                 bzero((void *)nv, sizeof (nvram_24xx_t));
 960 
 961                 /*
 962                  * Set default initialization control block.
 963                  */
 964                 nv->nvram_version[0] = LSB(ICB_24XX_VERSION);
 965                 nv->nvram_version[1] = MSB(ICB_24XX_VERSION);
 966 
 967                 nv->version[0] = 1;
 968                 nv->max_frame_length[1] = 8;
 969                 nv->execution_throttle[0] = 16;
 970                 nv->exchange_count[0] = 128;
 971                 nv->max_luns_per_target[0] = 8;
 972 
 973                 idpromlen = 32;
 974 
 975                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
 976                 if (rval = ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
 977                     DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
 978                     &idpromlen) != DDI_PROP_SUCCESS) {
 979 
 980                         cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
 981                             "property, rval=%x", QL_NAME, ha->instance, rval);
 982 
 983                         nv->port_name[0] = 33;
 984                         nv->port_name[3] = 224;
 985                         nv->port_name[4] = 139;
 986                         nv->port_name[7] = (uint8_t)
 987                             (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
 988                 } else {
 989                         nv->port_name[2] = idprombuf[2];
 990                         nv->port_name[3] = idprombuf[3];
 991                         nv->port_name[4] = idprombuf[4];
 992                         nv->port_name[5] = idprombuf[5];
 993                         nv->port_name[6] = idprombuf[6];
 994                         nv->port_name[7] = idprombuf[7];
 995                         nv->port_name[0] = (uint8_t)
 996                             (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
 997                 }
 998 
 999                 cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using default "
1000                     "HBA parameters and temporary "
1001                     "WWPN: %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
1002                     ha->instance, nv->port_name[0], nv->port_name[1],
1003                     nv->port_name[2], nv->port_name[3], nv->port_name[4],
1004                     nv->port_name[5], nv->port_name[6], nv->port_name[7]);
1005 
1006                 nv->login_retry_count[0] = 8;
1007 
1008                 nv->firmware_options_1[0] = BIT_2 | BIT_1;
1009                 nv->firmware_options_1[1] = BIT_5;
1010                 nv->firmware_options_2[0] = BIT_5;
1011                 nv->firmware_options_2[1] = BIT_4;
1012                 nv->firmware_options_3[1] = BIT_6;
1013 
1014                 /*
1015                  * Set default host adapter parameters
1016                  */
1017                 nv->host_p[0] = BIT_4 | BIT_1;
1018                 nv->host_p[1] = BIT_3 | BIT_2;
1019                 nv->reset_delay = 5;
1020                 nv->max_luns_per_target[0] = 128;
1021                 nv->port_down_retry_count[0] = 30;
1022                 nv->link_down_timeout[0] = 30;
1023 
1024                 if (CFG_IST(ha, CFG_CTRL_8081)) {
1025                         nv->firmware_options_3[2] = BIT_4;
1026                         nv->feature_mask_l[0] = 9;
1027                         nv->ext_blk.version[0] = 1;
1028                         nv->ext_blk.fcf_vlan_match = 1;
1029                         nv->ext_blk.fcf_vlan_id[0] = LSB(1002);
1030                         nv->ext_blk.fcf_vlan_id[1] = MSB(1002);
1031                         nv->fw.isp8001.e_node_mac_addr[1] = 2;
1032                         nv->fw.isp8001.e_node_mac_addr[2] = 3;
1033                         nv->fw.isp8001.e_node_mac_addr[3] = 4;
1034                         nv->fw.isp8001.e_node_mac_addr[4] = MSB(ha->instance);
1035                         nv->fw.isp8001.e_node_mac_addr[5] = LSB(ha->instance);
1036                 }
1037 
1038                 rval = QL_FUNCTION_FAILED;
1039         }
1040 
1041         /* Check for adapter node name (big endian). */
1042         for (index = 0; index < 8; index++) {
1043                 if (nv->node_name[index] != 0) {
1044                         break;
1045                 }
1046         }
1047 
1048         /* Copy port name if no node name (big endian). */
1049         if (index == 8) {
1050                 bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
1051                 nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
1052                 nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
1053         }
1054 
1055         /* Reset initialization control blocks. */
1056         bzero((void *)icb, sizeof (ql_init_24xx_cb_t));
1057 
1058         /* Get driver properties. */
1059         ql_24xx_properties(ha, nv);
1060 
1061         cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
1062             "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
1063             QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
1064             nv->port_name[2], nv->port_name[3], nv->port_name[4],
1065             nv->port_name[5], nv->port_name[6], nv->port_name[7],
1066             nv->node_name[0], nv->node_name[1], nv->node_name[2],
1067             nv->node_name[3], nv->node_name[4], nv->node_name[5],
1068             nv->node_name[6], nv->node_name[7]);
1069 
1070         /*
1071          * Copy over NVRAM Firmware Initialization Control Block.
1072          */
1073         dst = (caddr_t)icb;
1074         src = (caddr_t)&nv->version;
1075         index = (uint32_t)((uintptr_t)&icb->response_q_inpointer[0] -
1076             (uintptr_t)icb);
1077         while (index--) {
1078                 *dst++ = *src++;
1079         }
1080         icb->login_retry_count[0] = nv->login_retry_count[0];
1081         icb->login_retry_count[1] = nv->login_retry_count[1];
1082         icb->link_down_on_nos[0] = nv->link_down_on_nos[0];
1083         icb->link_down_on_nos[1] = nv->link_down_on_nos[1];
1084 
1085         dst = (caddr_t)&icb->interrupt_delay_timer;
1086         src = (caddr_t)&nv->interrupt_delay_timer;
1087         index = (uint32_t)((uintptr_t)&icb->qos -
1088             (uintptr_t)&icb->interrupt_delay_timer);
1089         while (index--) {
1090                 *dst++ = *src++;
1091         }
1092 
1093         /*
1094          * Setup driver firmware options.
1095          */
1096         if (CFG_IST(ha, CFG_CTRL_8081)) {
1097                 dst = (caddr_t)icb->enode_mac_addr;
1098                 src = (caddr_t)nv->fw.isp8001.e_node_mac_addr;
1099                 index = sizeof (nv->fw.isp8001.e_node_mac_addr);
1100                 while (index--) {
1101                         *dst++ = *src++;
1102                 }
1103                 dst = (caddr_t)&icb->ext_blk;
1104                 src = (caddr_t)&nv->ext_blk;
1105                 index = sizeof (ql_ext_icb_8100_t);
1106                 while (index--) {
1107                         *dst++ = *src++;
1108                 }
1109                 EL(ha, "e_node_mac_addr=%02x-%02x-%02x-%02x-%02x-%02x\n",
1110                     icb->enode_mac_addr[0], icb->enode_mac_addr[1],
1111                     icb->enode_mac_addr[2], icb->enode_mac_addr[3],
1112                     icb->enode_mac_addr[4], icb->enode_mac_addr[5]);
1113         } else {
1114                 icb->firmware_options_1[0] = (uint8_t)
1115                     (icb->firmware_options_1[0] | BIT_1);
1116                 icb->firmware_options_1[1] = (uint8_t)
1117                     (icb->firmware_options_1[1] | BIT_5 | BIT_2);
1118                 icb->firmware_options_3[0] = (uint8_t)
1119                     (icb->firmware_options_3[0] | BIT_1);
1120         }
1121         icb->firmware_options_1[0] = (uint8_t)(icb->firmware_options_1[0] &
1122             ~(BIT_5 | BIT_4));
1123         icb->firmware_options_1[1] = (uint8_t)(icb->firmware_options_1[1] |
1124             BIT_6);
1125         icb->firmware_options_2[0] = (uint8_t)(icb->firmware_options_2[0] &
1126             ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
1127         if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
1128                 icb->firmware_options_2[1] = (uint8_t)
1129                     (icb->firmware_options_2[1] | BIT_4);
1130         } else {
1131                 icb->firmware_options_2[1] = (uint8_t)
1132                     (icb->firmware_options_2[1] & ~BIT_4);
1133         }
1134 
1135         icb->firmware_options_3[0] = (uint8_t)(icb->firmware_options_3[0] &
1136             ~BIT_7);
1137 
1138         /* enable special N port 2 N port login behaviour */
1139         if (CFG_IST(ha, CFG_CTRL_2425)) {
1140                 icb->firmware_options_3[1] =
1141                     (uint8_t)(icb->firmware_options_3[1] | BIT_0);
1142         }
1143 
1144         icb->execution_throttle[0] = 0xff;
1145         icb->execution_throttle[1] = 0xff;
1146 
1147         /*
1148          * Set host adapter parameters
1149          */
1150         ADAPTER_STATE_LOCK(ha);
1151         ha->nvram_version = CHAR_TO_SHORT(nv->nvram_version[0],
1152             nv->nvram_version[1]);
1153         nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
1154             (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
1155         nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
1156             (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
1157         ha->cfg_flags &= ~(CFG_DISABLE_RISC_CODE_LOAD | CFG_LR_SUPPORT |
1158             CFG_SET_CACHE_LINE_SIZE_1 | CFG_MULTI_CHIP_ADAPTER);
1159         ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
1160         if (CFG_IST(ha, CFG_CTRL_81XX) && nv->enhanced_features[0] & BIT_0) {
1161                 ha->cfg_flags |= CFG_LR_SUPPORT;
1162         }
1163         ADAPTER_STATE_UNLOCK(ha);
1164 
1165         ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
1166             nv->execution_throttle[1]);
1167         ha->loop_reset_delay = nv->reset_delay;
1168         ha->port_down_retry_count = CHAR_TO_SHORT(nv->port_down_retry_count[0],
1169             nv->port_down_retry_count[1]);
1170         w1 = CHAR_TO_SHORT(icb->login_timeout[0], icb->login_timeout[1]);
1171         ha->r_a_tov = (uint16_t)(w1 < R_A_TOV_DEFAULT ? R_A_TOV_DEFAULT : w1);
1172         ha->maximum_luns_per_target = CHAR_TO_SHORT(
1173             nv->max_luns_per_target[0], nv->max_luns_per_target[1]);
1174         if (ha->maximum_luns_per_target == 0) {
1175                 ha->maximum_luns_per_target++;
1176         }
1177 
1178         /* ISP2422 Serial Link Control */
1179         if (CFG_IST(ha, CFG_CTRL_2422)) {
1180                 ha->serdes_param[0] = CHAR_TO_SHORT(nv->fw.isp2400.swing_opt[0],
1181                     nv->fw.isp2400.swing_opt[1]);
1182                 ha->serdes_param[1] = CHAR_TO_SHORT(nv->fw.isp2400.swing_1g[0],
1183                     nv->fw.isp2400.swing_1g[1]);
1184                 ha->serdes_param[2] = CHAR_TO_SHORT(nv->fw.isp2400.swing_2g[0],
1185                     nv->fw.isp2400.swing_2g[1]);
1186                 ha->serdes_param[3] = CHAR_TO_SHORT(nv->fw.isp2400.swing_4g[0],
1187                     nv->fw.isp2400.swing_4g[1]);
1188         }
1189 
1190         /*
1191          * Setup ring parameters in initialization control block
1192          */
1193         w1 = REQUEST_ENTRY_CNT;
1194         icb->request_q_length[0] = LSB(w1);
1195         icb->request_q_length[1] = MSB(w1);
1196         w1 = RESPONSE_ENTRY_CNT;
1197         icb->response_q_length[0] = LSB(w1);
1198         icb->response_q_length[1] = MSB(w1);
1199 
1200         icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
1201         icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
1202         icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
1203         icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
1204         icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
1205         icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
1206         icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
1207         icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
1208 
1209         icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
1210         icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
1211         icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
1212         icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
1213         icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
1214         icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
1215         icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
1216         icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
1217 
1218         /*
1219          * Setup IP initialization control block
1220          */
1221         ip_icb->version = IP_ICB_24XX_VERSION;
1222 
1223         ip_icb->ip_firmware_options[0] = (uint8_t)
1224             (ip_icb->ip_firmware_options[0] | BIT_2);
1225 
1226         if (rval != QL_SUCCESS) {
1227                 EL(ha, "failed, rval = %xh\n", rval);
1228         } else {
1229                 /*EMPTY*/
1230                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1231         }
1232         return (rval);
1233 }
1234 
1235 /*
1236  * ql_lock_nvram
1237  *      Locks NVRAM access and returns starting address of NVRAM.
1238  *
1239  * Input:
1240  *      ha:     adapter state pointer.
1241  *      addr:   pointer for start address.
1242  *      flags:  Are mutually exclusive:
1243  *              LNF_NVRAM_DATA --> get nvram
1244  *              LNF_VPD_DATA --> get vpd data (24/25xx only).
1245  *
1246  * Returns:
1247  *      ql local function return status code.
1248  *
1249  * Context:
1250  *      Kernel context.
1251  */
1252 int
1253 ql_lock_nvram(ql_adapter_state_t *ha, uint32_t *addr, uint32_t flags)
1254 {
1255         int     i;
1256 
1257         if ((flags & LNF_NVRAM_DATA) && (flags & LNF_VPD_DATA)) {
1258                 EL(ha, "invalid options for function");
1259                 return (QL_FUNCTION_FAILED);
1260         }
1261 
1262         if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1263                 if ((flags & LNF_NVRAM_DATA) == 0) {
1264                         EL(ha, "invalid 2312/2322 option for HBA");
1265                         return (QL_FUNCTION_FAILED);
1266                 }
1267 
1268                 /* if function number is non-zero, then adjust offset */
1269                 *addr = ha->flash_nvram_addr;
1270 
1271                 /* Try to get resource lock. Wait for 10 seconds max */
1272                 for (i = 0; i < 10000; i++) {
1273                         /* if nvram busy bit is reset, acquire sema */
1274                         if ((RD16_IO_REG(ha, nvram) & 0x8000) == 0) {
1275                                 WRT16_IO_REG(ha, host_to_host_sema, 1);
1276                                 drv_usecwait(MILLISEC);
1277                                 if (RD16_IO_REG(ha, host_to_host_sema) & 1) {
1278                                         break;
1279                                 }
1280                         }
1281                         drv_usecwait(MILLISEC);
1282                 }
1283                 if ((RD16_IO_REG(ha, host_to_host_sema) & 1) == 0) {
1284                         cmn_err(CE_WARN, "%s(%d): unable to get NVRAM lock",
1285                             QL_NAME, ha->instance);
1286                         return (QL_FUNCTION_FAILED);
1287                 }
1288         } else if (CFG_IST(ha, CFG_CTRL_2422)) {
1289                 if (flags & LNF_VPD_DATA) {
1290                         *addr = NVRAM_DATA_ADDR | ha->flash_vpd_addr;
1291                 } else if (flags & LNF_NVRAM_DATA) {
1292                         *addr = NVRAM_DATA_ADDR | ha->flash_nvram_addr;
1293                 } else {
1294                         EL(ha, "invalid 2422 option for HBA");
1295                         return (QL_FUNCTION_FAILED);
1296                 }
1297 
1298                 GLOBAL_HW_LOCK();
1299         } else if (CFG_IST(ha, CFG_CTRL_258081)) {
1300                 if (flags & LNF_VPD_DATA) {
1301                         *addr = ha->flash_data_addr | ha->flash_vpd_addr;
1302                 } else if (flags & LNF_NVRAM_DATA) {
1303                         *addr = ha->flash_data_addr | ha->flash_nvram_addr;
1304                 } else {
1305                         EL(ha, "invalid 2581 option for HBA");
1306                         return (QL_FUNCTION_FAILED);
1307                 }
1308 
1309                 GLOBAL_HW_LOCK();
1310         } else {
1311                 if ((flags & LNF_NVRAM_DATA) == 0) {
1312                         EL(ha, "invalid option for HBA");
1313                         return (QL_FUNCTION_FAILED);
1314                 }
1315                 *addr = 0;
1316                 GLOBAL_HW_LOCK();
1317         }
1318 
1319         return (QL_SUCCESS);
1320 }
1321 
1322 /*
1323  * ql_release_nvram
1324  *      Releases NVRAM access.
1325  *
1326  * Input:
1327  *      ha:     adapter state pointer.
1328  *
1329  * Context:
1330  *      Kernel context.
1331  */
1332 void
1333 ql_release_nvram(ql_adapter_state_t *ha)
1334 {
1335         if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1336                 /* Release resource lock */
1337                 WRT16_IO_REG(ha, host_to_host_sema, 0);
1338         } else {
1339                 GLOBAL_HW_UNLOCK();
1340         }
1341 }
1342 
1343 /*
1344  * ql_23_properties
1345  *      Copies driver properties to NVRAM or adapter structure.
1346  *
1347  *      Driver properties are by design global variables and hidden
1348  *      completely from administrators. Knowledgeable folks can
1349  *      override the default values using driver.conf
1350  *
1351  * Input:
1352  *      ha:     adapter state pointer.
1353  *      nv:     NVRAM structure pointer.
1354  *
1355  * Context:
1356  *      Kernel context.
1357  */
1358 static void
1359 ql_23_properties(ql_adapter_state_t *ha, nvram_t *nv)
1360 {
1361         uint32_t        data, cnt;
1362 
1363         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1364 
1365         /* Get frame payload size. */
1366         if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1367                 data = 2048;
1368         }
1369         if (data == 512 || data == 1024 || data == 2048) {
1370                 nv->max_frame_length[0] = LSB(data);
1371                 nv->max_frame_length[1] = MSB(data);
1372         } else {
1373                 EL(ha, "invalid parameter value for 'max-frame-length': "
1374                     "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1375                     nv->max_frame_length[0], nv->max_frame_length[1]));
1376         }
1377 
1378         /* Get max IOCB allocation. */
1379         nv->max_iocb_allocation[0] = 0;
1380         nv->max_iocb_allocation[1] = 1;
1381 
1382         /* Get execution throttle. */
1383         if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1384                 data = 32;
1385         }
1386         if (data != 0 && data < 65536) {
1387                 nv->execution_throttle[0] = LSB(data);
1388                 nv->execution_throttle[1] = MSB(data);
1389         } else {
1390                 EL(ha, "invalid parameter value for 'execution-throttle': "
1391                     "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1392                     nv->execution_throttle[0], nv->execution_throttle[1]));
1393         }
1394 
1395         /* Get Login timeout. */
1396         if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1397                 data = 3;
1398         }
1399         if (data < 256) {
1400                 nv->login_timeout = (uint8_t)data;
1401         } else {
1402                 EL(ha, "invalid parameter value for 'login-timeout': "
1403                     "%d; using nvram value of %d\n", data, nv->login_timeout);
1404         }
1405 
1406         /* Get retry count. */
1407         if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1408                 data = 4;
1409         }
1410         if (data < 256) {
1411                 nv->login_retry_count = (uint8_t)data;
1412         } else {
1413                 EL(ha, "invalid parameter value for 'login-retry-count': "
1414                     "%d; using nvram value of %d\n", data,
1415                     nv->login_retry_count);
1416         }
1417 
1418         /* Get adapter hard loop ID enable. */
1419         data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1420         if (data == 0) {
1421                 nv->firmware_options[0] =
1422                     (uint8_t)(nv->firmware_options[0] & ~BIT_0);
1423         } else if (data == 1) {
1424                 nv->firmware_options[0] =
1425                     (uint8_t)(nv->firmware_options[0] | BIT_0);
1426         } else if (data != 0xffffffff) {
1427                 EL(ha, "invalid parameter value for "
1428                     "'enable-adapter-hard-loop-ID': %d; using nvram value "
1429                     "of %d\n", data, nv->firmware_options[0] & BIT_0 ? 1 : 0);
1430         }
1431 
1432         /* Get adapter hard loop ID. */
1433         data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1434         if (data < 126) {
1435                 nv->hard_address[0] = (uint8_t)data;
1436         } else if (data != 0xffffffff) {
1437                 EL(ha, "invalid parameter value for 'adapter-hard-loop-ID': "
1438                     "%d; using nvram value of %d\n",
1439                     data, nv->hard_address[0]);
1440         }
1441 
1442         /* Get LIP reset. */
1443         if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1444             0xffffffff) {
1445                 data = 0;
1446         }
1447         if (data == 0) {
1448                 nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_1);
1449         } else if (data == 1) {
1450                 nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_1);
1451         } else {
1452                 EL(ha, "invalid parameter value for "
1453                     "'enable-LIP-reset-on-bus-reset': %d; using nvram value "
1454                     "of %d\n", data, nv->host_p[1] & BIT_1 ? 1 : 0);
1455         }
1456 
1457         /* Get LIP full login. */
1458         if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1459             0xffffffff) {
1460                 data = 1;
1461         }
1462         if (data == 0) {
1463                 nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1464         } else if (data == 1) {
1465                 nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1466         } else {
1467                 EL(ha, "invalid parameter value for "
1468                     "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1469                     "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1470         }
1471 
1472         /* Get target reset. */
1473         if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1474             0xffffffff) {
1475                 data = 0;
1476         }
1477         if (data == 0) {
1478                 nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1479         } else if (data == 1) {
1480                 nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1481         } else {
1482                 EL(ha, "invalid parameter value for "
1483                     "'enable-target-reset-on-bus-reset': %d; using nvram "
1484                     "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1485         }
1486 
1487         /* Get reset delay. */
1488         if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1489                 data = 5;
1490         }
1491         if (data != 0 && data < 256) {
1492                 nv->reset_delay = (uint8_t)data;
1493         } else {
1494                 EL(ha, "invalid parameter value for 'reset-delay': %d; "
1495                     "using nvram value of %d", data, nv->reset_delay);
1496         }
1497 
1498         /* Get port down retry count. */
1499         if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1500                 data = 8;
1501         }
1502         if (data < 256) {
1503                 nv->port_down_retry_count = (uint8_t)data;
1504         } else {
1505                 EL(ha, "invalid parameter value for 'port-down-retry-count':"
1506                     " %d; using nvram value of %d\n", data,
1507                     nv->port_down_retry_count);
1508         }
1509 
1510         /* Get connection mode setting. */
1511         if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1512                 data = 2;
1513         }
1514         cnt = CFG_IST(ha, CFG_CTRL_2200) ? 3 : 2;
1515         if (data <= cnt) {
1516                 nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] &
1517                     ~(BIT_6 | BIT_5 | BIT_4));
1518                 nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
1519                     (uint8_t)(data << 4));
1520         } else {
1521                 EL(ha, "invalid parameter value for 'connection-options': "
1522                     "%d; using nvram value of %d\n", data,
1523                     (nv->add_fw_opt[0] >> 4) & 0x3);
1524         }
1525 
1526         /* Get data rate setting. */
1527         if ((CFG_IST(ha, CFG_CTRL_2200)) == 0) {
1528                 if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1529                         data = 2;
1530                 }
1531                 if (data < 3) {
1532                         nv->special_options[1] = (uint8_t)
1533                             (nv->special_options[1] & 0x3f);
1534                         nv->special_options[1] = (uint8_t)
1535                             (nv->special_options[1] | (uint8_t)(data << 6));
1536                 } else {
1537                         EL(ha, "invalid parameter value for 'fc-data-rate': "
1538                             "%d; using nvram value of %d\n", data,
1539                             (nv->special_options[1] >> 6) & 0x3);
1540                 }
1541         }
1542 
1543         /* Get adapter id string for Sun branded 23xx only */
1544         if ((CFG_IST(ha, CFG_CTRL_2300)) && nv->adapInfo[0] != 0) {
1545                 (void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
1546                     nv->adapInfo);
1547         }
1548 
1549         /* Get IP FW container count. */
1550         ha->ip_init_ctrl_blk.cb.cc[0] = LSB(ql_ip_buffer_count);
1551         ha->ip_init_ctrl_blk.cb.cc[1] = MSB(ql_ip_buffer_count);
1552 
1553         /* Get IP low water mark. */
1554         ha->ip_init_ctrl_blk.cb.low_water_mark[0] = LSB(ql_ip_low_water);
1555         ha->ip_init_ctrl_blk.cb.low_water_mark[1] = MSB(ql_ip_low_water);
1556 
1557         /* Get IP fast register post count. */
1558         ha->ip_init_ctrl_blk.cb.fast_post_reg_count[0] =
1559             ql_ip_fast_post_count;
1560 
1561         ADAPTER_STATE_LOCK(ha);
1562 
1563         ql_common_properties(ha);
1564 
1565         ADAPTER_STATE_UNLOCK(ha);
1566 
1567         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1568 }
1569 
1570 /*
1571  * ql_common_properties
1572  *      Driver properties adapter structure.
1573  *
1574  *      Driver properties are by design global variables and hidden
1575  *      completely from administrators. Knowledgeable folks can
1576  *      override the default values using driver.conf
1577  *
1578  * Input:
1579  *      ha:     adapter state pointer.
1580  *
1581  * Context:
1582  *      Kernel context.
1583  */
1584 void
1585 ql_common_properties(ql_adapter_state_t *ha)
1586 {
1587         uint32_t        data;
1588 
1589         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1590 
1591         /* Get extended logging trace buffer size. */
1592         if ((data = ql_get_prop(ha, "set-ext-log-buffer-size")) !=
1593             0xffffffff && data != 0) {
1594                 char            *new_trace;
1595                 uint32_t        new_size;
1596 
1597                 if (ha->el_trace_desc->trace_buffer != NULL) {
1598                         new_size = 1024 * data;
1599                         new_trace = (char *)kmem_zalloc(new_size, KM_SLEEP);
1600 
1601                         if (new_trace == NULL) {
1602                                 cmn_err(CE_WARN, "%s(%d): can't get new"
1603                                     " trace buffer",
1604                                     QL_NAME, ha->instance);
1605                         } else {
1606                                 /* free the previous */
1607                                 kmem_free(ha->el_trace_desc->trace_buffer,
1608                                     ha->el_trace_desc->trace_buffer_size);
1609                                 /* Use the new one */
1610                                 ha->el_trace_desc->trace_buffer = new_trace;
1611                                 ha->el_trace_desc->trace_buffer_size = new_size;
1612                         }
1613                 }
1614 
1615         }
1616 
1617         /* Get extended logging enable. */
1618         if ((data = ql_get_prop(ha, "extended-logging")) == 0xffffffff ||
1619             data == 0) {
1620                 ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1621         } else if (data == 1) {
1622                 ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1623         } else {
1624                 EL(ha, "invalid parameter value for 'extended-logging': %d;"
1625                     " using default value of 0\n", data);
1626                 ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1627         }
1628 
1629         /* Get extended logging trace disable. */
1630         if ((data = ql_get_prop(ha, "disable-extended-logging-trace")) ==
1631             0xffffffff || data == 0) {
1632                 ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1633         } else if (data == 1) {
1634                 ha->cfg_flags |= CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1635         } else {
1636                 EL(ha, "invalid parameter value for "
1637                     "'disable-extended-logging-trace': %d;"
1638                     " using default value of 0\n", data);
1639                 ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1640         }
1641 
1642         /* Get FCP 2 Error Recovery. */
1643         if ((data = ql_get_prop(ha, "enable-FCP-2-error-recovery")) ==
1644             0xffffffff || data == 1) {
1645                 ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1646         } else if (data == 0) {
1647                 ha->cfg_flags &= ~CFG_ENABLE_FCP_2_SUPPORT;
1648         } else {
1649                 EL(ha, "invalid parameter value for "
1650                     "'enable-FCP-2-error-recovery': %d; using nvram value of "
1651                     "1\n", data);
1652                 ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1653         }
1654 
1655 #ifdef QL_DEBUG_LEVEL_2
1656         ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1657 #endif
1658 
1659         /* Get port down retry delay. */
1660         if ((data = ql_get_prop(ha, "port-down-retry-delay")) == 0xffffffff) {
1661                 ha->port_down_retry_delay = PORT_RETRY_TIME;
1662         } else if (data < 256) {
1663                 ha->port_down_retry_delay = (uint8_t)data;
1664         } else {
1665                 EL(ha, "invalid parameter value for 'port-down-retry-delay':"
1666                     " %d; using default value of %d", data, PORT_RETRY_TIME);
1667                 ha->port_down_retry_delay = PORT_RETRY_TIME;
1668         }
1669 
1670         /* Get queue full retry count. */
1671         if ((data = ql_get_prop(ha, "queue-full-retry-count")) == 0xffffffff) {
1672                 ha->qfull_retry_count = 16;
1673         } else if (data < 256) {
1674                 ha->qfull_retry_count = (uint8_t)data;
1675         } else {
1676                 EL(ha, "invalid parameter value for 'queue-full-retry-count':"
1677                     " %d; using default value of 16", data);
1678                 ha->qfull_retry_count = 16;
1679         }
1680 
1681         /* Get queue full retry delay. */
1682         if ((data = ql_get_prop(ha, "queue-full-retry-delay")) == 0xffffffff) {
1683                 ha->qfull_retry_delay = PORT_RETRY_TIME;
1684         } else if (data < 256) {
1685                 ha->qfull_retry_delay = (uint8_t)data;
1686         } else {
1687                 EL(ha, "invalid parameter value for 'queue-full-retry-delay':"
1688                     " %d; using default value of %d", data, PORT_RETRY_TIME);
1689                 ha->qfull_retry_delay = PORT_RETRY_TIME;
1690         }
1691 
1692         /* Get loop down timeout. */
1693         if ((data = ql_get_prop(ha, "link-down-timeout")) == 0xffffffff) {
1694                 data = 0;
1695         } else if (data > 255) {
1696                 EL(ha, "invalid parameter value for 'link-down-timeout': %d;"
1697                     " using nvram value of 0\n", data);
1698                 data = 0;
1699         }
1700         ha->loop_down_abort_time = (uint8_t)(LOOP_DOWN_TIMER_START - data);
1701         if (ha->loop_down_abort_time == LOOP_DOWN_TIMER_START) {
1702                 ha->loop_down_abort_time--;
1703         } else if (ha->loop_down_abort_time <= LOOP_DOWN_TIMER_END) {
1704                 ha->loop_down_abort_time = LOOP_DOWN_TIMER_END + 1;
1705         }
1706 
1707         /* Get link down error enable. */
1708         if ((data = ql_get_prop(ha, "enable-link-down-error")) == 0xffffffff ||
1709             data == 1) {
1710                 ha->cfg_flags |= CFG_ENABLE_LINK_DOWN_REPORTING;
1711         } else if (data == 0) {
1712                 ha->cfg_flags &= ~CFG_ENABLE_LINK_DOWN_REPORTING;
1713         } else {
1714                 EL(ha, "invalid parameter value for 'link-down-error': %d;"
1715                     " using default value of 1\n", data);
1716         }
1717 
1718         /*
1719          * Get firmware dump flags.
1720          *      TAKE_FW_DUMP_ON_MAILBOX_TIMEOUT         BIT_0
1721          *      TAKE_FW_DUMP_ON_ISP_SYSTEM_ERROR        BIT_1
1722          *      TAKE_FW_DUMP_ON_DRIVER_COMMAND_TIMEOUT  BIT_2
1723          *      TAKE_FW_DUMP_ON_LOOP_OFFLINE_TIMEOUT    BIT_3
1724          */
1725         ha->cfg_flags &= ~(CFG_DUMP_MAILBOX_TIMEOUT |
1726             CFG_DUMP_ISP_SYSTEM_ERROR | CFG_DUMP_DRIVER_COMMAND_TIMEOUT |
1727             CFG_DUMP_LOOP_OFFLINE_TIMEOUT);
1728         if ((data = ql_get_prop(ha, "firmware-dump-flags")) != 0xffffffff) {
1729                 if (data & BIT_0) {
1730                         ha->cfg_flags |= CFG_DUMP_MAILBOX_TIMEOUT;
1731                 }
1732                 if (data & BIT_1) {
1733                         ha->cfg_flags |= CFG_DUMP_ISP_SYSTEM_ERROR;
1734                 }
1735                 if (data & BIT_2) {
1736                         ha->cfg_flags |= CFG_DUMP_DRIVER_COMMAND_TIMEOUT;
1737                 }
1738                 if (data & BIT_3) {
1739                         ha->cfg_flags |= CFG_DUMP_LOOP_OFFLINE_TIMEOUT;
1740                 }
1741         }
1742 
1743         /* Get the PCI max read request size override. */
1744         ha->pci_max_read_req = 0;
1745         if ((data = ql_get_prop(ha, "pci-max-read-request")) != 0xffffffff &&
1746             data != 0) {
1747                 ha->pci_max_read_req = (uint16_t)(data);
1748         }
1749 
1750         /*
1751          * Set default fw wait, adjusted for slow FCF's.
1752          * Revisit when FCF's as fast as FC switches.
1753          */
1754         ha->fwwait = (uint8_t)(CFG_IST(ha, CFG_CTRL_8081) ? 45 : 10);
1755         /* Get the attach fw_ready override value. */
1756         if ((data = ql_get_prop(ha, "init-loop-sync-wait")) != 0xffffffff) {
1757                 if (data > 0 && data <= 240) {
1758                         ha->fwwait = (uint8_t)data;
1759                 } else {
1760                         EL(ha, "invalid parameter value for "
1761                             "'init-loop-sync-wait': %d; using default "
1762                             "value of %d\n", data, ha->fwwait);
1763                 }
1764         }
1765 
1766         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1767 }
1768 
1769 /*
1770  * ql_24xx_properties
1771  *      Copies driver properties to NVRAM or adapter structure.
1772  *
1773  *      Driver properties are by design global variables and hidden
1774  *      completely from administrators. Knowledgeable folks can
1775  *      override the default values using /etc/system.
1776  *
1777  * Input:
1778  *      ha:     adapter state pointer.
1779  *      nv:     NVRAM structure pointer.
1780  *
1781  * Context:
1782  *      Kernel context.
1783  */
1784 static void
1785 ql_24xx_properties(ql_adapter_state_t *ha, nvram_24xx_t *nv)
1786 {
1787         uint32_t        data;
1788 
1789         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1790 
1791         /* Get frame size */
1792         if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1793                 data = 2048;
1794         }
1795         if (data == 512 || data == 1024 || data == 2048 || data == 2112) {
1796                 nv->max_frame_length[0] = LSB(data);
1797                 nv->max_frame_length[1] = MSB(data);
1798         } else {
1799                 EL(ha, "invalid parameter value for 'max-frame-length': %d;"
1800                     " using nvram default of %d\n", data, CHAR_TO_SHORT(
1801                     nv->max_frame_length[0], nv->max_frame_length[1]));
1802         }
1803 
1804         /* Get execution throttle. */
1805         if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1806                 data = 32;
1807         }
1808         if (data != 0 && data < 65536) {
1809                 nv->execution_throttle[0] = LSB(data);
1810                 nv->execution_throttle[1] = MSB(data);
1811         } else {
1812                 EL(ha, "invalid parameter value for 'execution-throttle':"
1813                     " %d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1814                     nv->execution_throttle[0], nv->execution_throttle[1]));
1815         }
1816 
1817         /* Get Login timeout. */
1818         if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1819                 data = 3;
1820         }
1821         if (data < 65536) {
1822                 nv->login_timeout[0] = LSB(data);
1823                 nv->login_timeout[1] = MSB(data);
1824         } else {
1825                 EL(ha, "invalid parameter value for 'login-timeout': %d; "
1826                     "using nvram value of %d\n", data, CHAR_TO_SHORT(
1827                     nv->login_timeout[0], nv->login_timeout[1]));
1828         }
1829 
1830         /* Get retry count. */
1831         if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1832                 data = 4;
1833         }
1834         if (data < 65536) {
1835                 nv->login_retry_count[0] = LSB(data);
1836                 nv->login_retry_count[1] = MSB(data);
1837         } else {
1838                 EL(ha, "invalid parameter value for 'login-retry-count': "
1839                     "%d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1840                     nv->login_retry_count[0], nv->login_retry_count[1]));
1841         }
1842 
1843         /* Get adapter hard loop ID enable. */
1844         data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1845         if (data == 0) {
1846                 nv->firmware_options_1[0] =
1847                     (uint8_t)(nv->firmware_options_1[0] & ~BIT_0);
1848         } else if (data == 1) {
1849                 nv->firmware_options_1[0] =
1850                     (uint8_t)(nv->firmware_options_1[0] | BIT_0);
1851         } else if (data != 0xffffffff) {
1852                 EL(ha, "invalid parameter value for "
1853                     "'enable-adapter-hard-loop-ID': %d; using nvram value "
1854                     "of %d\n", data,
1855                     nv->firmware_options_1[0] & BIT_0 ? 1 : 0);
1856         }
1857 
1858         /* Get adapter hard loop ID. */
1859         data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1860         if (data < 126) {
1861                 nv->hard_address[0] = LSB(data);
1862                 nv->hard_address[1] = MSB(data);
1863         } else if (data != 0xffffffff) {
1864                 EL(ha, "invalid parameter value for 'adapter-hard-loop-ID':"
1865                     " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1866                     nv->hard_address[0], nv->hard_address[1]));
1867         }
1868 
1869         /* Get LIP reset. */
1870         if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1871             0xffffffff) {
1872                 data = 0;
1873         }
1874         if (data == 0) {
1875                 ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET;
1876         } else if (data == 1) {
1877                 ha->cfg_flags |= CFG_ENABLE_LIP_RESET;
1878         } else {
1879                 EL(ha, "invalid parameter value for "
1880                     "'enable-LIP-reset-on-bus-reset': %d; using value of 0\n",
1881                     data);
1882         }
1883 
1884         /* Get LIP full login. */
1885         if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1886             0xffffffff) {
1887                 data = 1;
1888         }
1889         if (data == 0) {
1890                 nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1891         } else if (data == 1) {
1892                 nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1893         } else {
1894                 EL(ha, "invalid parameter value for "
1895                     "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1896                     "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1897         }
1898 
1899         /* Get target reset. */
1900         if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1901             0xffffffff) {
1902                 data = 0;
1903         }
1904         if (data == 0) {
1905                 nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1906         } else if (data == 1) {
1907                 nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1908         } else {
1909                 EL(ha, "invalid parameter value for "
1910                     "'enable-target-reset-on-bus-reset': %d; using nvram "
1911                     "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1912         }
1913 
1914         /* Get reset delay. */
1915         if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1916                 data = 5;
1917         }
1918         if (data != 0 && data < 256) {
1919                 nv->reset_delay = (uint8_t)data;
1920         } else {
1921                 EL(ha, "invalid parameter value for 'reset-delay': %d; "
1922                     "using nvram value of %d", data, nv->reset_delay);
1923         }
1924 
1925         /* Get port down retry count. */
1926         if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1927                 data = 8;
1928         }
1929         if (data < 256) {
1930                 nv->port_down_retry_count[0] = LSB(data);
1931                 nv->port_down_retry_count[1] = MSB(data);
1932         } else {
1933                 EL(ha, "invalid parameter value for 'port-down-retry-count':"
1934                     " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1935                     nv->port_down_retry_count[0],
1936                     nv->port_down_retry_count[1]));
1937         }
1938 
1939         if (!(CFG_IST(ha, CFG_CTRL_8081))) {
1940                 /* Get connection mode setting. */
1941                 if ((data = ql_get_prop(ha, "connection-options")) ==
1942                     0xffffffff) {
1943                         data = 2;
1944                 }
1945                 if (data <= 2) {
1946                         nv->firmware_options_2[0] = (uint8_t)
1947                             (nv->firmware_options_2[0] &
1948                             ~(BIT_6 | BIT_5 | BIT_4));
1949                         nv->firmware_options_2[0] = (uint8_t)
1950                             (nv->firmware_options_2[0] | (uint8_t)(data << 4));
1951                 } else {
1952                         EL(ha, "invalid parameter value for 'connection-"
1953                             "options': %d; using nvram value of %d\n", data,
1954                             (nv->firmware_options_2[0] >> 4) & 0x3);
1955                 }
1956 
1957                 /* Get data rate setting. */
1958                 if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1959                         data = 2;
1960                 }
1961                 if ((CFG_IST(ha, CFG_CTRL_2422) && data < 4) ||
1962                     (CFG_IST(ha, CFG_CTRL_258081) && data < 5)) {
1963                         nv->firmware_options_3[1] = (uint8_t)
1964                             (nv->firmware_options_3[1] & 0x1f);
1965                         nv->firmware_options_3[1] = (uint8_t)
1966                             (nv->firmware_options_3[1] | (uint8_t)(data << 5));
1967                 } else {
1968                         EL(ha, "invalid parameter value for 'fc-data-rate': "
1969                             "%d; using nvram value of %d\n", data,
1970                             (nv->firmware_options_3[1] >> 5) & 0x7);
1971                 }
1972         }
1973 
1974         /* Get IP FW container count. */
1975         ha->ip_init_ctrl_blk.cb24.cc[0] = LSB(ql_ip_buffer_count);
1976         ha->ip_init_ctrl_blk.cb24.cc[1] = MSB(ql_ip_buffer_count);
1977 
1978         /* Get IP low water mark. */
1979         ha->ip_init_ctrl_blk.cb24.low_water_mark[0] = LSB(ql_ip_low_water);
1980         ha->ip_init_ctrl_blk.cb24.low_water_mark[1] = MSB(ql_ip_low_water);
1981 
1982         ADAPTER_STATE_LOCK(ha);
1983 
1984         /* Get enable flash load. */
1985         if ((data = ql_get_prop(ha, "enable-flash-load")) == 0xffffffff ||
1986             data == 0) {
1987                 ha->cfg_flags &= ~CFG_LOAD_FLASH_FW;
1988         } else if (data == 1) {
1989                 ha->cfg_flags |= CFG_LOAD_FLASH_FW;
1990         } else {
1991                 EL(ha, "invalid parameter value for 'enable-flash-load': "
1992                     "%d; using default value of 0\n", data);
1993         }
1994 
1995         /* Enable firmware extended tracing */
1996         if ((data = ql_get_prop(ha, "enable-fwexttrace")) != 0xffffffff) {
1997                 if (data != 0) {
1998                         ha->cfg_flags |= CFG_ENABLE_FWEXTTRACE;
1999                 }
2000         }
2001 
2002         /* Enable firmware fc tracing */
2003         if ((data = ql_get_prop(ha, "enable-fwfcetrace")) != 0xffffffff) {
2004                 ha->cfg_flags |= CFG_ENABLE_FWFCETRACE;
2005                 ha->fwfcetraceopt = data;
2006         }
2007 
2008         /* Enable fast timeout */
2009         if ((data = ql_get_prop(ha, "enable-fasttimeout")) != 0xffffffff) {
2010                 if (data != 0) {
2011                         ha->cfg_flags |= CFG_FAST_TIMEOUT;
2012                 }
2013         }
2014 
2015         ql_common_properties(ha);
2016 
2017         ADAPTER_STATE_UNLOCK(ha);
2018 
2019         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2020 }
2021 
2022 /*
2023  * ql_get_prop
2024  *      Get property value from configuration file.
2025  *
2026  * Input:
2027  *      ha= adapter state pointer.
2028  *      string = property string pointer.
2029  *
2030  * Returns:
2031  *      0xFFFFFFFF = no property else property value.
2032  *
2033  * Context:
2034  *      Kernel context.
2035  */
2036 uint32_t
2037 ql_get_prop(ql_adapter_state_t *ha, char *string)
2038 {
2039         char            buf[256];
2040         uint32_t        data = 0xffffffff;
2041 
2042         /*
2043          * Look for a adapter instance NPIV (virtual port) specific parameter
2044          */
2045         if (CFG_IST(ha, CFG_CTRL_24258081)) {
2046                 (void) sprintf(buf, "hba%d-vp%d-%s", ha->instance,
2047                     ha->vp_index, string);
2048                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2049                 data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2050                     buf, (int)0xffffffff);
2051         }
2052 
2053         /*
2054          * Get adapter instance parameter if a vp specific one isn't found.
2055          */
2056         if (data == 0xffffffff) {
2057                 (void) sprintf(buf, "hba%d-%s", ha->instance, string);
2058                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2059                 data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip,
2060                     0, buf, (int)0xffffffff);
2061         }
2062 
2063         /* Adapter instance parameter found? */
2064         if (data == 0xffffffff) {
2065                 /* No, get default parameter. */
2066                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2067                 data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2068                     string, (int)0xffffffff);
2069         }
2070 
2071         return (data);
2072 }
2073 
2074 /*
2075  * ql_check_isp_firmware
2076  *      Checks if using already loaded RISC code or drivers copy.
2077  *      If using already loaded code, save a copy of it.
2078  *
2079  * Input:
2080  *      ha = adapter state pointer.
2081  *
2082  * Returns:
2083  *      ql local function return status code.
2084  *
2085  * Context:
2086  *      Kernel context.
2087  */
2088 static int
2089 ql_check_isp_firmware(ql_adapter_state_t *ha)
2090 {
2091         int             rval;
2092         uint16_t        word_count;
2093         uint32_t        byte_count;
2094         uint32_t        fw_size, *lptr;
2095         caddr_t         bufp;
2096         uint16_t        risc_address = (uint16_t)ha->risc_fw[0].addr;
2097 
2098         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2099 
2100         /* Test for firmware running. */
2101         if (CFG_IST(ha, CFG_CTRL_8021)) {
2102                 if (ql_8021_idc_handler(ha) != NX_DEV_READY) {
2103                         rval = QL_FUNCTION_FAILED;
2104                 } else {
2105                         rval = ql_start_firmware(ha);
2106                 }
2107         } else if (CFG_IST(ha, CFG_DISABLE_RISC_CODE_LOAD)) {
2108                 if (ha->risc_code != NULL) {
2109                         kmem_free(ha->risc_code, ha->risc_code_size);
2110                         ha->risc_code = NULL;
2111                         ha->risc_code_size = 0;
2112                 }
2113 
2114                 /* Get RISC code length. */
2115                 rval = ql_rd_risc_ram(ha, risc_address + 3, ha->request_dvma,
2116                     1);
2117                 if (rval == QL_SUCCESS) {
2118                         lptr = (uint32_t *)ha->request_ring_bp;
2119                         fw_size = *lptr << 1;
2120 
2121                         if ((bufp = kmem_alloc(fw_size, KM_SLEEP)) != NULL) {
2122                                 ha->risc_code_size = fw_size;
2123                                 ha->risc_code = bufp;
2124                                 ha->fw_transfer_size = 128;
2125 
2126                                 /* Dump RISC code. */
2127                                 do {
2128                                         if (fw_size > ha->fw_transfer_size) {
2129                                                 byte_count =
2130                                                     ha->fw_transfer_size;
2131                                         } else {
2132                                                 byte_count = fw_size;
2133                                         }
2134 
2135                                         word_count =
2136                                             (uint16_t)(byte_count >> 1);
2137 
2138                                         rval = ql_rd_risc_ram(ha, risc_address,
2139                                             ha->request_dvma, word_count);
2140                                         if (rval != QL_SUCCESS) {
2141                                                 kmem_free(ha->risc_code,
2142                                                     ha->risc_code_size);
2143                                                 ha->risc_code = NULL;
2144                                                 ha->risc_code_size = 0;
2145                                                 break;
2146                                         }
2147 
2148                                         (void) ddi_dma_sync(
2149                                             ha->hba_buf.dma_handle,
2150                                             REQUEST_Q_BUFFER_OFFSET,
2151                                             byte_count,
2152                                             DDI_DMA_SYNC_FORKERNEL);
2153                                         ddi_rep_get16(ha->hba_buf.acc_handle,
2154                                             (uint16_t *)bufp,
2155                                             (uint16_t *)ha->request_ring_bp,
2156                                             word_count, DDI_DEV_AUTOINCR);
2157 
2158                                         risc_address += word_count;
2159                                         fw_size -= byte_count;
2160                                         bufp    += byte_count;
2161                                 } while (fw_size != 0);
2162                         }
2163                         rval = QL_FUNCTION_FAILED;
2164                 }
2165         } else {
2166                 rval = QL_FUNCTION_FAILED;
2167         }
2168 
2169         if (rval != QL_SUCCESS) {
2170                 EL(ha, "Load RISC code\n");
2171         } else {
2172                 /*EMPTY*/
2173                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2174         }
2175         return (rval);
2176 }
2177 
2178 /*
2179  * Chip diagnostics
2180  *      Test chip for proper operation.
2181  *
2182  * Input:
2183  *      ha = adapter state pointer.
2184  *
2185  * Returns:
2186  *      ql local function return status code.
2187  *
2188  * Context:
2189  *      Kernel context.
2190  */
2191 static int
2192 ql_chip_diag(ql_adapter_state_t *ha)
2193 {
2194         ql_mbx_data_t   mr;
2195         int             rval;
2196         int32_t         retries = 4;
2197         uint16_t        id;
2198 
2199         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2200 
2201         do {
2202                 /* Reset ISP chip. */
2203                 TASK_DAEMON_LOCK(ha);
2204                 ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
2205                 TASK_DAEMON_UNLOCK(ha);
2206 
2207                 /* For ISP2200A reduce firmware load size. */
2208                 if (CFG_IST(ha, CFG_CTRL_2200) &&
2209                     RD16_IO_REG(ha, mailbox_out[7]) == 4) {
2210                         ha->fw_transfer_size = 128;
2211                 } else {
2212                         ha->fw_transfer_size = REQUEST_QUEUE_SIZE;
2213                 }
2214 
2215                 rval = QL_SUCCESS;
2216                 if (!(CFG_IST(ha, CFG_CTRL_8021))) {
2217                         ql_reset_chip(ha);
2218 
2219                         /* Check product ID of chip */
2220                         mr.mb[1] = RD16_IO_REG(ha, mailbox_out[1]);
2221                         mr.mb[2] = RD16_IO_REG(ha, mailbox_out[2]);
2222                         mr.mb[3] = RD16_IO_REG(ha, mailbox_out[3]);
2223 
2224                         if (ha->device_id == 0x5432 ||
2225                             ha->device_id == 0x8432) {
2226                                 id = 0x2432;
2227                         } else if (ha->device_id == 0x5422 ||
2228                             ha->device_id == 0x8422) {
2229                                 id = 0x2422;
2230                         } else {
2231                                 id = ha->device_id;
2232                         }
2233 
2234                         if (mr.mb[1] == PROD_ID_1 &&
2235                             (mr.mb[2] == PROD_ID_2 || mr.mb[2] == PROD_ID_2a) &&
2236                             (mr.mb[3] == PROD_ID_3 || mr.mb[3] == id)) {
2237                                 ha->adapter_stats->revlvl.isp2200 =
2238                                     RD16_IO_REG(ha, mailbox_out[4]);
2239                                 ha->adapter_stats->revlvl.risc =
2240                                     RD16_IO_REG(ha, mailbox_out[5]);
2241                                 ha->adapter_stats->revlvl.frmbfr =
2242                                     RD16_IO_REG(ha, mailbox_out[6]);
2243                                 ha->adapter_stats->revlvl.riscrom =
2244                                     RD16_IO_REG(ha, mailbox_out[7]);
2245                         } else {
2246                                 cmn_err(CE_WARN, "%s(%d) - prod id failed!, "
2247                                     "mb1=%xh, mb2=%xh, mb3=%xh", QL_NAME,
2248                                     ha->instance, mr.mb[1], mr.mb[2], mr.mb[3]);
2249                                 rval = QL_FUNCTION_FAILED;
2250                         }
2251                 } else if (!(ha->task_daemon_flags & FIRMWARE_LOADED)) {
2252                         break;
2253                 }
2254 
2255                 if (rval == QL_SUCCESS) {
2256                         /* Wrap Incoming Mailboxes Test. */
2257                         mr.mb[1] = 0xAAAA;
2258                         mr.mb[2] = 0x5555;
2259                         mr.mb[3] = 0xAA55;
2260                         mr.mb[4] = 0x55AA;
2261                         mr.mb[5] = 0xA5A5;
2262                         mr.mb[6] = 0x5A5A;
2263                         mr.mb[7] = 0x2525;
2264                         rval = ql_mbx_wrap_test(ha, &mr);
2265                         if (rval == QL_SUCCESS) {
2266                                 if (mr.mb[1] != 0xAAAA ||
2267                                     mr.mb[2] != 0x5555 ||
2268                                     mr.mb[3] != 0xAA55 ||
2269                                     mr.mb[4] != 0x55AA ||
2270                                     mr.mb[5] != 0xA5A5 ||
2271                                     mr.mb[6] != 0x5A5A ||
2272                                     mr.mb[7] != 0x2525) {
2273                                         rval = QL_FUNCTION_FAILED;
2274                                         (void) ql_flash_errlog(ha,
2275                                             FLASH_ERRLOG_ISP_ERR, 0,
2276                                             RD16_IO_REG(ha, hccr),
2277                                             RD16_IO_REG(ha, istatus));
2278                                 }
2279                         } else {
2280                                 cmn_err(CE_WARN, "%s(%d) - reg test failed="
2281                                     "%xh!", QL_NAME, ha->instance, rval);
2282                         }
2283                 }
2284         } while ((retries-- != 0) && (rval != QL_SUCCESS));
2285 
2286         if (rval != QL_SUCCESS) {
2287                 EL(ha, "failed, rval = %xh\n", rval);
2288         } else {
2289                 /*EMPTY*/
2290                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2291         }
2292         return (rval);
2293 }
2294 
2295 /*
2296  * ql_load_isp_firmware
2297  *      Load and start RISC firmware.
2298  *      Uses request ring for DMA buffer.
2299  *
2300  * Input:
2301  *      ha = adapter state pointer.
2302  *
2303  * Returns:
2304  *      ql local function return status code.
2305  *
2306  * Context:
2307  *      Kernel context.
2308  */
2309 int
2310 ql_load_isp_firmware(ql_adapter_state_t *vha)
2311 {
2312         caddr_t                 risc_code_address;
2313         uint32_t                risc_address, risc_code_size;
2314         int                     rval;
2315         uint32_t                word_count, cnt;
2316         size_t                  byte_count;
2317         ql_adapter_state_t      *ha = vha->pha;
2318 
2319         if (CFG_IST(ha, CFG_CTRL_8021)) {
2320                 rval = ql_8021_load_risc(ha);
2321         } else {
2322                 if (CFG_IST(ha, CFG_CTRL_81XX)) {
2323                         ql_mps_reset(ha);
2324                 }
2325 
2326                 if (CFG_IST(ha, CFG_LOAD_FLASH_FW)) {
2327                         return (ql_load_flash_fw(ha));
2328                 }
2329 
2330                 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2331 
2332                 /* Load firmware segments */
2333                 for (cnt = 0; cnt < MAX_RISC_CODE_SEGMENTS &&
2334                     ha->risc_fw[cnt].code != NULL; cnt++) {
2335 
2336                         risc_code_address = ha->risc_fw[cnt].code;
2337                         risc_address = ha->risc_fw[cnt].addr;
2338                         risc_code_size = ha->risc_fw[cnt].length;
2339 
2340                         while (risc_code_size) {
2341                                 if (CFG_IST(ha, CFG_CTRL_242581)) {
2342                                         word_count = ha->fw_transfer_size >> 2;
2343                                         if (word_count > risc_code_size) {
2344                                                 word_count = risc_code_size;
2345                                         }
2346                                         byte_count = word_count << 2;
2347 
2348                                         ddi_rep_put32(ha->hba_buf.acc_handle,
2349                                             (uint32_t *)risc_code_address,
2350                                             (uint32_t *)ha->request_ring_bp,
2351                                             word_count, DDI_DEV_AUTOINCR);
2352                                 } else {
2353                                         word_count = ha->fw_transfer_size >> 1;
2354                                         if (word_count > risc_code_size) {
2355                                                 word_count = risc_code_size;
2356                                         }
2357                                         byte_count = word_count << 1;
2358 
2359                                         ddi_rep_put16(ha->hba_buf.acc_handle,
2360                                             (uint16_t *)risc_code_address,
2361                                             (uint16_t *)ha->request_ring_bp,
2362                                             word_count, DDI_DEV_AUTOINCR);
2363                                 }
2364 
2365                                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
2366                                     REQUEST_Q_BUFFER_OFFSET, byte_count,
2367                                     DDI_DMA_SYNC_FORDEV);
2368 
2369                                 rval = ql_wrt_risc_ram(ha, risc_address,
2370                                     ha->request_dvma, word_count);
2371                                 if (rval != QL_SUCCESS) {
2372                                         EL(ha, "failed, load=%xh\n", rval);
2373                                         cnt = MAX_RISC_CODE_SEGMENTS;
2374                                         break;
2375                                 }
2376 
2377                                 risc_address += word_count;
2378                                 risc_code_size -= word_count;
2379                                 risc_code_address += byte_count;
2380                         }
2381                 }
2382         }
2383 
2384         /* Start firmware. */
2385         if (rval == QL_SUCCESS) {
2386                 rval = ql_start_firmware(ha);
2387         }
2388 
2389         if (rval != QL_SUCCESS) {
2390                 EL(ha, "failed, rval = %xh\n", rval);
2391         } else {
2392                 /*EMPTY*/
2393                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2394         }
2395 
2396         return (rval);
2397 }
2398 
2399 /*
2400  * ql_load_flash_fw
2401  *      Gets ISP24xx firmware from flash and loads ISP.
2402  *
2403  * Input:
2404  *      ha:     adapter state pointer.
2405  *
2406  * Returns:
2407  *      ql local function return status code.
2408  */
2409 static int
2410 ql_load_flash_fw(ql_adapter_state_t *ha)
2411 {
2412         int             rval;
2413         uint8_t         seg_cnt;
2414         uint32_t        risc_address, xfer_size, count, *bp, faddr;
2415         uint32_t        risc_code_size = 0;
2416 
2417         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2418 
2419         faddr = ha->flash_data_addr | ha->flash_fw_addr;
2420 
2421         for (seg_cnt = 0; seg_cnt < 2; seg_cnt++) {
2422                 xfer_size = ha->fw_transfer_size >> 2;
2423                 do {
2424                         GLOBAL_HW_LOCK();
2425 
2426                         /* Read data from flash. */
2427                         bp = (uint32_t *)ha->request_ring_bp;
2428                         for (count = 0; count < xfer_size; count++) {
2429                                 rval = ql_24xx_read_flash(ha, faddr++, bp);
2430                                 if (rval != QL_SUCCESS) {
2431                                         break;
2432                                 }
2433                                 ql_chg_endian((uint8_t *)bp++, 4);
2434                         }
2435 
2436                         GLOBAL_HW_UNLOCK();
2437 
2438                         if (rval != QL_SUCCESS) {
2439                                 EL(ha, "24xx_read_flash failed=%xh\n", rval);
2440                                 break;
2441                         }
2442 
2443                         if (risc_code_size == 0) {
2444                                 bp = (uint32_t *)ha->request_ring_bp;
2445                                 risc_address = bp[2];
2446                                 risc_code_size = bp[3];
2447                                 ha->risc_fw[seg_cnt].addr = risc_address;
2448                         }
2449 
2450                         if (risc_code_size < xfer_size) {
2451                                 faddr -= xfer_size - risc_code_size;
2452                                 xfer_size = risc_code_size;
2453                         }
2454 
2455                         (void) ddi_dma_sync(ha->hba_buf.dma_handle,
2456                             REQUEST_Q_BUFFER_OFFSET, xfer_size << 2,
2457                             DDI_DMA_SYNC_FORDEV);
2458 
2459                         rval = ql_wrt_risc_ram(ha, risc_address,
2460                             ha->request_dvma, xfer_size);
2461                         if (rval != QL_SUCCESS) {
2462                                 EL(ha, "ql_wrt_risc_ram failed=%xh\n", rval);
2463                                 break;
2464                         }
2465 
2466                         risc_address += xfer_size;
2467                         risc_code_size -= xfer_size;
2468                 } while (risc_code_size);
2469 
2470                 if (rval != QL_SUCCESS) {
2471                         break;
2472                 }
2473         }
2474 
2475         /* Start firmware. */
2476         if (rval == QL_SUCCESS) {
2477                 rval = ql_start_firmware(ha);
2478         }
2479 
2480         if (rval != QL_SUCCESS) {
2481                 EL(ha, "failed, rval = %xh\n", rval);
2482         } else {
2483                 /*EMPTY*/
2484                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2485         }
2486         return (rval);
2487 }
2488 
2489 /*
2490  * ql_start_firmware
2491  *      Starts RISC code.
2492  *
2493  * Input:
2494  *      ha = adapter state pointer.
2495  *
2496  * Returns:
2497  *      ql local function return status code.
2498  *
2499  * Context:
2500  *      Kernel context.
2501  */
2502 int
2503 ql_start_firmware(ql_adapter_state_t *vha)
2504 {
2505         int                     rval, rval2;
2506         uint32_t                data;
2507         ql_mbx_data_t           mr;
2508         ql_adapter_state_t      *ha = vha->pha;
2509 
2510         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2511 
2512         if (CFG_IST(ha, CFG_CTRL_8021)) {
2513                 /* Save firmware version. */
2514                 rval = ql_get_fw_version(ha, &mr, MAILBOX_TOV);
2515                 ha->fw_major_version = mr.mb[1];
2516                 ha->fw_minor_version = mr.mb[2];
2517                 ha->fw_subminor_version = mr.mb[3];
2518                 ha->fw_attributes = mr.mb[6];
2519         } else if ((rval = ql_verify_checksum(ha)) == QL_SUCCESS) {
2520                 /* Verify checksum of loaded RISC code. */
2521                 /* Start firmware execution. */
2522                 (void) ql_execute_fw(ha);
2523 
2524                 /* Save firmware version. */
2525                 (void) ql_get_fw_version(ha, &mr, MAILBOX_TOV);
2526                 ha->fw_major_version = mr.mb[1];
2527                 ha->fw_minor_version = mr.mb[2];
2528                 ha->fw_subminor_version = mr.mb[3];
2529                 ha->fw_ext_memory_size = ((SHORT_TO_LONG(mr.mb[4], mr.mb[5]) -
2530                     0x100000) + 1) * 4;
2531                 ha->fw_attributes = mr.mb[6];
2532 
2533                 if (CFG_IST(ha, CFG_CTRL_81XX)) {
2534                         ha->phy_fw_major_version = LSB(mr.mb[8]);
2535                         ha->phy_fw_minor_version = MSB(mr.mb[9]);
2536                         ha->phy_fw_subminor_version = LSB(mr.mb[9]);
2537                         ha->mpi_fw_major_version = LSB(mr.mb[10]);
2538                         ha->mpi_fw_minor_version = MSB(mr.mb[11]);
2539                         ha->mpi_fw_subminor_version = LSB(mr.mb[11]);
2540                         ha->mpi_capability_list = SHORT_TO_LONG(mr.mb[13],
2541                             mr.mb[12]);
2542                         if ((rval2 = ql_flash_access(ha, FAC_GET_SECTOR_SIZE,
2543                             0, 0, &data)) == QL_SUCCESS) {
2544                                 ha->xioctl->fdesc.block_size = data << 2;
2545                                 QL_PRINT_10(CE_CONT, "(%d): fdesc.block_size="
2546                                     "%xh\n", ha->instance,
2547                                     ha->xioctl->fdesc.block_size);
2548                         } else {
2549                                 EL(ha, "flash_access status=%xh\n", rval2);
2550                         }
2551                 }
2552 
2553                 /* Set Serdes Transmit Parameters. */
2554                 if (CFG_IST(ha, CFG_CTRL_2422) && ha->serdes_param[0] & BIT_0) {
2555                         mr.mb[1] = ha->serdes_param[0];
2556                         mr.mb[2] = ha->serdes_param[1];
2557                         mr.mb[3] = ha->serdes_param[2];
2558                         mr.mb[4] = ha->serdes_param[3];
2559                         (void) ql_serdes_param(ha, &mr);
2560                 }
2561         }
2562         /* ETS workaround */
2563         if (CFG_IST(ha, CFG_CTRL_81XX) && ql_enable_ets) {
2564                 if (ql_get_firmware_option(ha, &mr) == QL_SUCCESS) {
2565                         mr.mb[2] = (uint16_t)
2566                             (mr.mb[2] | FO2_FCOE_512_MAX_MEM_WR_BURST);
2567                         (void) ql_set_firmware_option(ha, &mr);
2568                 }
2569         }
2570         if (rval != QL_SUCCESS) {
2571                 ha->task_daemon_flags &= ~FIRMWARE_LOADED;
2572                 EL(ha, "failed, rval = %xh\n", rval);
2573         } else {
2574                 ha->task_daemon_flags |= FIRMWARE_LOADED;
2575                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2576         }
2577         return (rval);
2578 }
2579 
2580 /*
2581  * ql_set_cache_line
2582  *      Sets PCI cache line parameter.
2583  *
2584  * Input:
2585  *      ha = adapter state pointer.
2586  *
2587  * Returns:
2588  *      ql local function return status code.
2589  *
2590  * Context:
2591  *      Kernel context.
2592  */
2593 int
2594 ql_set_cache_line(ql_adapter_state_t *ha)
2595 {
2596         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2597 
2598         /* Set the cache line. */
2599         if (CFG_IST(ha->pha, CFG_SET_CACHE_LINE_SIZE_1)) {
2600                 /* Set cache line register. */
2601                 ql_pci_config_put8(ha->pha, PCI_CONF_CACHE_LINESZ, 1);
2602         }
2603 
2604         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2605 
2606         return (QL_SUCCESS);
2607 }
2608 
2609 /*
2610  * ql_init_rings
2611  *      Initializes firmware and ring pointers.
2612  *
2613  *      Beginning of response ring has initialization control block
2614  *      already built by nvram config routine.
2615  *
2616  * Input:
2617  *      ha = adapter state pointer.
2618  *      ha->hba_buf = request and response rings
2619  *      ha->init_ctrl_blk = initialization control block
2620  *
2621  * Returns:
2622  *      ql local function return status code.
2623  *
2624  * Context:
2625  *      Kernel context.
2626  */
2627 int
2628 ql_init_rings(ql_adapter_state_t *vha2)
2629 {
2630         int                     rval, rval2;
2631         uint16_t                index;
2632         ql_mbx_data_t           mr;
2633         ql_adapter_state_t      *ha = vha2->pha;
2634 
2635         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2636 
2637         /* Clear outstanding commands array. */
2638         for (index = 0; index < MAX_OUTSTANDING_COMMANDS; index++) {
2639                 ha->outstanding_cmds[index] = NULL;
2640         }
2641         ha->osc_index = 1;
2642 
2643         ha->pending_cmds.first = NULL;
2644         ha->pending_cmds.last = NULL;
2645 
2646         /* Initialize firmware. */
2647         ha->request_ring_ptr = ha->request_ring_bp;
2648         ha->req_ring_index = 0;
2649         ha->req_q_cnt = REQUEST_ENTRY_CNT - 1;
2650         ha->response_ring_ptr = ha->response_ring_bp;
2651         ha->rsp_ring_index = 0;
2652 
2653         if (ha->flags & VP_ENABLED) {
2654                 ql_adapter_state_t      *vha;
2655                 uint16_t                cnt;
2656                 uint32_t                max_vports;
2657                 ql_init_24xx_cb_t       *icb = &ha->init_ctrl_blk.cb24;
2658 
2659                 max_vports = (CFG_IST(ha, CFG_CTRL_2422) ?
2660                     MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS);
2661                 bzero(icb->vp_count,
2662                     ((uintptr_t)icb + sizeof (ql_init_24xx_cb_t)) -
2663                     (uintptr_t)icb->vp_count);
2664                 icb->vp_count[0] = (uint8_t)max_vports;
2665 
2666                 /* Allow connection option 2. */
2667                 icb->global_vp_option[0] = BIT_1;
2668 
2669                 for (cnt = 0, vha = ha->vp_next; cnt < max_vports &&
2670                     vha != NULL; vha = vha->vp_next, cnt++) {
2671 
2672                         index = (uint8_t)(vha->vp_index - 1);
2673                         bcopy(vha->loginparams.node_ww_name.raw_wwn,
2674                             icb->vpc[index].node_name, 8);
2675                         bcopy(vha->loginparams.nport_ww_name.raw_wwn,
2676                             icb->vpc[index].port_name, 8);
2677 
2678                         icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
2679                             VPO_INITIATOR_MODE_ENABLED;
2680                         if (vha->flags & VP_ENABLED) {
2681                                 icb->vpc[index].options = (uint8_t)
2682                                     (icb->vpc[index].options | VPO_ENABLED);
2683                         }
2684                 }
2685         }
2686 
2687         for (index = 0; index < 2; index++) {
2688                 rval = ql_init_firmware(ha);
2689                 if (rval == QL_COMMAND_ERROR) {
2690                         EL(ha, "stopping firmware\n");
2691                         (void) ql_stop_firmware(ha);
2692                 } else {
2693                         break;
2694                 }
2695         }
2696 
2697         if (rval == QL_SUCCESS && (CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
2698                 /* Tell firmware to enable MBA_PORT_BYPASS_CHANGED event */
2699                 rval = ql_get_firmware_option(ha, &mr);
2700                 if (rval == QL_SUCCESS) {
2701                         mr.mb[1] = (uint16_t)(mr.mb[1] | BIT_9);
2702                         mr.mb[2] = 0;
2703                         mr.mb[3] = BIT_10;
2704                         rval = ql_set_firmware_option(ha, &mr);
2705                 }
2706         }
2707 
2708         if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWFCETRACE))) {
2709                 /* Firmware Fibre Channel Event Trace Buffer */
2710                 if ((rval2 = ql_get_dma_mem(ha, &ha->fwfcetracebuf, FWFCESIZE,
2711                     LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2712                         EL(ha, "fcetrace buffer alloc failed: %xh\n", rval2);
2713                 } else {
2714                         if ((rval2 = ql_fw_etrace(ha, &ha->fwfcetracebuf,
2715                             FTO_FCE_TRACE_ENABLE)) != QL_SUCCESS) {
2716                                 EL(ha, "fcetrace enable failed: %xh\n", rval2);
2717                                 ql_free_phys(ha, &ha->fwfcetracebuf);
2718                         }
2719                 }
2720         }
2721 
2722         if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE))) {
2723                 /* Firmware Extended Trace Buffer */
2724                 if ((rval2 = ql_get_dma_mem(ha, &ha->fwexttracebuf, FWEXTSIZE,
2725                     LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2726                         EL(ha, "exttrace buffer alloc failed: %xh\n", rval2);
2727                 } else {
2728                         if ((rval2 = ql_fw_etrace(ha, &ha->fwexttracebuf,
2729                             FTO_EXT_TRACE_ENABLE)) != QL_SUCCESS) {
2730                                 EL(ha, "exttrace enable failed: %xh\n", rval2);
2731                                 ql_free_phys(ha, &ha->fwexttracebuf);
2732                         }
2733                 }
2734         }
2735 
2736         if (rval == QL_SUCCESS && CFG_IST(ha, CFG_CTRL_MENLO)) {
2737                 ql_mbx_iocb_t   *pkt;
2738                 clock_t         timer;
2739 
2740                 /* Wait for firmware login of menlo. */
2741                 for (timer = 3000; timer; timer--) {
2742                         if (ha->flags & MENLO_LOGIN_OPERATIONAL) {
2743                                 break;
2744                         }
2745 
2746                         if (!(ha->flags & INTERRUPTS_ENABLED) ||
2747                             ddi_in_panic()) {
2748                                 if (INTERRUPT_PENDING(ha)) {
2749                                         (void) ql_isr((caddr_t)ha);
2750                                         INTR_LOCK(ha);
2751                                         ha->intr_claimed = B_TRUE;
2752                                         INTR_UNLOCK(ha);
2753                                 }
2754                         }
2755 
2756                         /* Delay for 1 tick (10 milliseconds). */
2757                         ql_delay(ha, 10000);
2758                 }
2759 
2760                 if (timer == 0) {
2761                         rval = QL_FUNCTION_TIMEOUT;
2762                 } else {
2763                         pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
2764                         if (pkt == NULL) {
2765                                 EL(ha, "failed, kmem_zalloc\n");
2766                                 rval = QL_MEMORY_ALLOC_FAILED;
2767                         } else {
2768                                 pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
2769                                 pkt->mvfy.entry_count = 1;
2770                                 pkt->mvfy.options_status =
2771                                     LE_16(VMF_DO_NOT_UPDATE_FW);
2772 
2773                                 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt,
2774                                     sizeof (ql_mbx_iocb_t));
2775                                 LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
2776                                 LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
2777 
2778                                 if (rval != QL_SUCCESS ||
2779                                     (pkt->mvfy.entry_status & 0x3c) != 0 ||
2780                                     pkt->mvfy.options_status != CS_COMPLETE) {
2781                                         EL(ha, "failed, status=%xh, es=%xh, "
2782                                             "cs=%xh, fc=%xh\n", rval,
2783                                             pkt->mvfy.entry_status & 0x3c,
2784                                             pkt->mvfy.options_status,
2785                                             pkt->mvfy.failure_code);
2786                                         if (rval == QL_SUCCESS) {
2787                                                 rval = QL_FUNCTION_FAILED;
2788                                         }
2789                                 }
2790 
2791                                 kmem_free(pkt, sizeof (ql_mbx_iocb_t));
2792                         }
2793                 }
2794         }
2795 
2796         if (rval != QL_SUCCESS) {
2797                 TASK_DAEMON_LOCK(ha);
2798                 ha->task_daemon_flags &= ~FIRMWARE_UP;
2799                 TASK_DAEMON_UNLOCK(ha);
2800                 EL(ha, "failed, rval = %xh\n", rval);
2801         } else {
2802                 TASK_DAEMON_LOCK(ha);
2803                 ha->task_daemon_flags |= FIRMWARE_UP;
2804                 TASK_DAEMON_UNLOCK(ha);
2805                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2806         }
2807         return (rval);
2808 }
2809 
2810 /*
2811  * ql_fw_ready
2812  *      Waits for firmware ready. If firmware becomes ready
2813  *      device queues and RISC code are synchronized.
2814  *
2815  * Input:
2816  *      ha = adapter state pointer.
2817  *      secs = max wait time, in seconds (0-255).
2818  *
2819  * Returns:
2820  *      ql local function return status code.
2821  *
2822  * Context:
2823  *      Kernel context.
2824  */
2825 int
2826 ql_fw_ready(ql_adapter_state_t *ha, uint8_t secs)
2827 {
2828         ql_mbx_data_t   mr;
2829         clock_t         timer;
2830         clock_t         dly = 250000;
2831         clock_t         sec_delay = MICROSEC / dly;
2832         clock_t         wait = secs * sec_delay;
2833         int             rval = QL_FUNCTION_FAILED;
2834         uint16_t        state = 0xffff;
2835 
2836         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2837 
2838         timer = ha->r_a_tov < secs ? secs : ha->r_a_tov;
2839         timer = (timer + 2) * sec_delay;
2840 
2841         /* Wait for ISP to finish LIP */
2842         while (timer != 0 && wait != 0 &&
2843             !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
2844 
2845                 rval = ql_get_firmware_state(ha, &mr);
2846                 if (rval == QL_SUCCESS) {
2847                         if (ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2848                             LOOP_DOWN)) {
2849                                 wait--;
2850                         } else if (mr.mb[1] != FSTATE_READY) {
2851                                 if (mr.mb[1] != FSTATE_WAIT_LOGIN) {
2852                                         wait--;
2853                                 }
2854                                 rval = QL_FUNCTION_FAILED;
2855                         } else {
2856                                 /* Firmware is ready. Get 2 * R_A_TOV. */
2857                                 rval = ql_get_timeout_parameters(ha,
2858                                     &ha->r_a_tov);
2859                                 if (rval != QL_SUCCESS) {
2860                                         EL(ha, "failed, get_timeout_param"
2861                                             "=%xh\n", rval);
2862                                 }
2863 
2864                                 /* Configure loop. */
2865                                 rval = ql_configure_loop(ha);
2866                                 (void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
2867 
2868                                 if (ha->task_daemon_flags &
2869                                     LOOP_RESYNC_NEEDED) {
2870                                         wait--;
2871                                         EL(ha, "loop trans; tdf=%xh\n",
2872                                             ha->task_daemon_flags);
2873                                 } else {
2874                                         break;
2875                                 }
2876                         }
2877                 } else {
2878                         wait--;
2879                 }
2880 
2881                 if (state != mr.mb[1]) {
2882                         EL(ha, "mailbox_reg[1] = %xh\n", mr.mb[1]);
2883                         state = mr.mb[1];
2884                 }
2885 
2886                 /* Delay for a tick if waiting. */
2887                 if (timer-- != 0 && wait != 0) {
2888                         if (timer % 4 == 0) {
2889                                 delay(drv_usectohz(dly));
2890                         } else {
2891                                 drv_usecwait(dly);
2892                         }
2893                 } else {
2894                         rval = QL_FUNCTION_TIMEOUT;
2895                 }
2896         }
2897 
2898         if (rval != QL_SUCCESS) {
2899                 EL(ha, "failed, rval = %xh\n", rval);
2900         } else {
2901                 /*EMPTY*/
2902                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2903         }
2904         return (rval);
2905 }
2906 
2907 /*
2908  * ql_configure_loop
2909  *      Setup configurations based on loop.
2910  *
2911  * Input:
2912  *      ha = adapter state pointer.
2913  *
2914  * Returns:
2915  *      ql local function return status code.
2916  *
2917  * Context:
2918  *      Kernel context.
2919  */
2920 static int
2921 ql_configure_loop(ql_adapter_state_t *ha)
2922 {
2923         int                     rval;
2924         ql_adapter_state_t      *vha;
2925 
2926         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2927 
2928         for (vha = ha; vha != NULL; vha = vha->vp_next) {
2929                 TASK_DAEMON_LOCK(ha);
2930                 if (!(vha->task_daemon_flags & LOOP_RESYNC_NEEDED) &&
2931                     vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2932                         TASK_DAEMON_UNLOCK(ha);
2933                         continue;
2934                 }
2935                 vha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
2936                 TASK_DAEMON_UNLOCK(ha);
2937 
2938                 rval = ql_configure_hba(vha);
2939                 if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2940                     (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2941                         rval = ql_configure_device_d_id(vha);
2942                         if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2943                             (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2944                                 (void) ql_configure_fabric(vha);
2945                         }
2946                 }
2947         }
2948 
2949         if (rval != QL_SUCCESS) {
2950                 EL(ha, "failed, rval = %xh\n", rval);
2951         } else {
2952                 /*EMPTY*/
2953                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2954         }
2955         return (rval);
2956 }
2957 
2958 /*
2959  * ql_configure_n_port_info
2960  *      Setup configurations based on N port 2 N port topology.
2961  *
2962  * Input:
2963  *      ha = adapter state pointer.
2964  *
2965  * Returns:
2966  *      ql local function return status code.
2967  *
2968  * Context:
2969  *      Kernel context.
2970  */
2971 static void
2972 ql_configure_n_port_info(ql_adapter_state_t *ha)
2973 {
2974         ql_tgt_t        tmp_tq;
2975         ql_tgt_t        *tq;
2976         uint8_t         *cb_port_name;
2977         ql_link_t       *link;
2978         int             index, rval;
2979 
2980         tq = &tmp_tq;
2981 
2982         /* Free existing target queues. */
2983         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
2984                 link = ha->dev[index].first;
2985                 while (link != NULL) {
2986                         tq = link->base_address;
2987                         link = link->next;
2988                         ql_remove_link(&ha->dev[index], &tq->device);
2989                         ql_dev_free(ha, tq);
2990                 }
2991         }
2992 
2993         /*
2994          * If the N_Port's WWPN is larger than our's then it has the
2995          * N_Port login initiative.  It will have determined that and
2996          * logged in with the firmware.  This results in a device
2997          * database entry.  In this situation we will later send up a PLOGI
2998          * by proxy for the N_Port to get things going.
2999          *
3000          * If the N_Ports WWPN is smaller then the firmware has the
3001          * N_Port login initiative and does a FLOGI in order to obtain the
3002          * N_Ports WWNN and WWPN.  These names are required later
3003          * during Leadvilles FLOGI.  No PLOGI is done by the firmware in
3004          * anticipation of a PLOGI via the driver from the upper layers.
3005          * Upon reciept of said PLOGI the driver issues an ELS PLOGI
3006          * pass-through command and the firmware assumes the s_id
3007          * and the N_Port assumes the d_id and Bob's your uncle.
3008          */
3009 
3010         /*
3011          * In N port 2 N port topology the FW provides a port database entry at
3012          * loop_id 0x7fe which allows us to acquire the Ports WWPN.
3013          */
3014         tq->d_id.b.al_pa = 0;
3015         tq->d_id.b.area = 0;
3016         tq->d_id.b.domain = 0;
3017         tq->loop_id = 0x7fe;
3018 
3019         rval = ql_get_port_database(ha, tq, PDF_NONE);
3020         if (rval == QL_SUCCESS || rval == QL_NOT_LOGGED_IN) {
3021                 ql_dev_id_list_t        *list;
3022                 uint32_t                list_size;
3023                 ql_mbx_data_t           mr;
3024                 port_id_t               d_id = {{{0, 0, 0}, 0}};
3025                 uint16_t                loop_id = 0;
3026 
3027                 cb_port_name = (uint8_t *)(CFG_IST(ha, CFG_CTRL_24258081) ?
3028                     &ha->init_ctrl_blk.cb24.port_name[0] :
3029                     &ha->init_ctrl_blk.cb.port_name[0]);
3030 
3031                 if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
3032                     (la_wwn_t *)cb_port_name) == 1)) {
3033                         EL(ha, "target port has N_Port login initiative\n");
3034                 } else {
3035                         EL(ha, "host port has N_Port login initiative\n");
3036                 }
3037 
3038                 /* Capture the N Ports WWPN */
3039 
3040                 bcopy((void *)&tq->port_name[0],
3041                     (void *)&ha->n_port->port_name[0], 8);
3042                 bcopy((void *)&tq->node_name[0],
3043                     (void *)&ha->n_port->node_name[0], 8);
3044 
3045                 /* Resolve an n_port_handle */
3046                 ha->n_port->n_port_handle = 0x7fe;
3047 
3048                 list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
3049                 list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
3050 
3051                 if (list != NULL &&
3052                     ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
3053                     QL_SUCCESS) {
3054                         if (mr.mb[1]) {
3055                                 EL(ha, "id list entries = %d\n", mr.mb[1]);
3056                                 for (index = 0; index < mr.mb[1]; index++) {
3057                                         ql_dev_list(ha, list, index,
3058                                             &d_id, &loop_id);
3059                                         ha->n_port->n_port_handle = loop_id;
3060                                 }
3061                         } else {
3062                                 for (index = 0; index <= LAST_LOCAL_LOOP_ID;
3063                                     index++) {
3064                                         /* resuse tq */
3065                                         tq->loop_id = (uint16_t)index;
3066                                         rval = ql_get_port_database(ha, tq,
3067                                             PDF_NONE);
3068                                         if (rval == QL_NOT_LOGGED_IN) {
3069                                                 if (tq->master_state ==
3070                                                     PD_STATE_PLOGI_PENDING) {
3071                                                         ha->n_port->
3072                                                             n_port_handle =
3073                                                             tq->loop_id;
3074                                                         break;
3075                                                 }
3076                                         } else {
3077                                                 ha->n_port->n_port_handle =
3078                                                     tq->loop_id;
3079                                                 break;
3080                                         }
3081                                 }
3082                         }
3083                 } else {
3084                         cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
3085                             QL_NAME, ha->instance, d_id.b24);
3086                 }
3087                 if (list != NULL) {
3088                         kmem_free(list, list_size);
3089                 }
3090         }
3091 }
3092 
3093 
3094 /*
3095  * ql_configure_hba
3096  *      Setup adapter context.
3097  *
3098  * Input:
3099  *      ha = adapter state pointer.
3100  *
3101  * Returns:
3102  *      ql local function return status code.
3103  *
3104  * Context:
3105  *      Kernel context.
3106  */
3107 static int
3108 ql_configure_hba(ql_adapter_state_t *ha)
3109 {
3110         uint8_t         *bp;
3111         int             rval;
3112         uint32_t        state;
3113         ql_mbx_data_t   mr;
3114 
3115         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3116 
3117         /* Get host addresses. */
3118         rval = ql_get_adapter_id(ha, &mr);
3119         if (rval == QL_SUCCESS) {
3120                 ha->topology = (uint8_t)(ha->topology &
3121                     ~(QL_N_PORT | QL_NL_PORT | QL_F_PORT | QL_FL_PORT));
3122 
3123                 /* Save Host d_id, alpa, loop ID. */
3124                 ha->loop_id = mr.mb[1];
3125                 ha->d_id.b.al_pa = LSB(mr.mb[2]);
3126                 ha->d_id.b.area = MSB(mr.mb[2]);
3127                 ha->d_id.b.domain = LSB(mr.mb[3]);
3128 
3129                 ADAPTER_STATE_LOCK(ha);
3130                 ha->flags &= ~FDISC_ENABLED;
3131 
3132                 /* Get loop topology. */
3133                 switch (mr.mb[6]) {
3134                 case CNX_LOOP_NO_FABRIC:
3135                         ha->topology = (uint8_t)(ha->topology | QL_NL_PORT);
3136                         break;
3137                 case CNX_FLPORT_IN_LOOP:
3138                         ha->topology = (uint8_t)(ha->topology | QL_FL_PORT);
3139                         break;
3140                 case CNX_NPORT_2_NPORT_P2P:
3141                 case CNX_NPORT_2_NPORT_NO_TGT_RSP:
3142                         ha->flags |= POINT_TO_POINT;
3143                         ha->topology = (uint8_t)(ha->topology | QL_N_PORT);
3144                         if (CFG_IST(ha, CFG_CTRL_2425)) {
3145                                 ql_configure_n_port_info(ha);
3146                         }
3147                         break;
3148                 case CNX_FLPORT_P2P:
3149                         ha->flags |= POINT_TO_POINT;
3150                         ha->topology = (uint8_t)(ha->topology | QL_F_PORT);
3151 
3152                         /* Get supported option. */
3153                         if (CFG_IST(ha, CFG_CTRL_24258081) &&
3154                             mr.mb[7] & GID_FP_NPIV_SUPPORT) {
3155                                 ha->flags |= FDISC_ENABLED;
3156                         }
3157                         /* Get VLAN ID, mac address */
3158                         if (CFG_IST(ha, CFG_CTRL_8081)) {
3159                                 ha->fabric_params = mr.mb[7];
3160                                 ha->fcoe_vlan_id = (uint16_t)(mr.mb[9] & 0xfff);
3161                                 ha->fcoe_fcf_idx = mr.mb[10];
3162                                 ha->fcoe_vnport_mac[0] = MSB(mr.mb[11]);
3163                                 ha->fcoe_vnport_mac[1] = LSB(mr.mb[11]);
3164                                 ha->fcoe_vnport_mac[2] = MSB(mr.mb[12]);
3165                                 ha->fcoe_vnport_mac[3] = LSB(mr.mb[12]);
3166                                 ha->fcoe_vnport_mac[4] = MSB(mr.mb[13]);
3167                                 ha->fcoe_vnport_mac[5] = LSB(mr.mb[13]);
3168                         }
3169                         break;
3170                 default:
3171                         QL_PRINT_2(CE_CONT, "(%d,%d): UNKNOWN topology=%xh, "
3172                             "d_id=%xh\n", ha->instance, ha->vp_index, mr.mb[6],
3173                             ha->d_id.b24);
3174                         rval = QL_FUNCTION_FAILED;
3175                         break;
3176                 }
3177                 ADAPTER_STATE_UNLOCK(ha);
3178 
3179                 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322 |
3180                     CFG_CTRL_24258081))) {
3181                         mr.mb[1] = 0;
3182                         mr.mb[2] = 0;
3183                         rval = ql_data_rate(ha, &mr);
3184                         if (rval != QL_SUCCESS) {
3185                                 EL(ha, "data_rate status=%xh\n", rval);
3186                                 state = FC_STATE_FULL_SPEED;
3187                         } else {
3188                                 ha->iidma_rate = mr.mb[1];
3189                                 if (mr.mb[1] == IIDMA_RATE_1GB) {
3190                                         state = FC_STATE_1GBIT_SPEED;
3191                                 } else if (mr.mb[1] == IIDMA_RATE_2GB) {
3192                                         state = FC_STATE_2GBIT_SPEED;
3193                                 } else if (mr.mb[1] == IIDMA_RATE_4GB) {
3194                                         state = FC_STATE_4GBIT_SPEED;
3195                                 } else if (mr.mb[1] == IIDMA_RATE_8GB) {
3196                                         state = FC_STATE_8GBIT_SPEED;
3197                                 } else if (mr.mb[1] == IIDMA_RATE_10GB) {
3198                                         state = FC_STATE_10GBIT_SPEED;
3199                                 } else {
3200                                         state = 0;
3201                                 }
3202                         }
3203                 } else {
3204                         ha->iidma_rate = IIDMA_RATE_1GB;
3205                         state = FC_STATE_FULL_SPEED;
3206                 }
3207                 ha->state = FC_PORT_STATE_MASK(ha->state) | state;
3208         } else if (rval == MBS_COMMAND_ERROR) {
3209                 EL(ha, "mbox cmd error, rval = %xh, mr.mb[1]=%hx\n",
3210                     rval, mr.mb[1]);
3211         }
3212 
3213         if (rval != QL_SUCCESS) {
3214                 EL(ha, "failed, rval = %xh\n", rval);
3215         } else {
3216                 bp = ha->loginparams.nport_ww_name.raw_wwn;
3217                 EL(ha, "topology=%xh, d_id=%xh, "
3218                     "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n",
3219                     ha->topology, ha->d_id.b24, bp[0], bp[1],
3220                     bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]);
3221         }
3222         return (rval);
3223 }
3224 
3225 /*
3226  * ql_configure_device_d_id
3227  *      Updates device loop ID.
3228  *      Also adds to device queue any new devices found on private loop.
3229  *
3230  * Input:
3231  *      ha = adapter state pointer.
3232  *
3233  * Returns:
3234  *      ql local function return status code.
3235  *
3236  * Context:
3237  *      Kernel context.
3238  */
3239 static int
3240 ql_configure_device_d_id(ql_adapter_state_t *ha)
3241 {
3242         port_id_t               d_id;
3243         ql_link_t               *link;
3244         int                     rval;
3245         int                     loop;
3246         ql_tgt_t                *tq;
3247         ql_dev_id_list_t        *list;
3248         uint32_t                list_size;
3249         uint16_t                index, loop_id;
3250         ql_mbx_data_t           mr;
3251         uint8_t                 retries = MAX_DEVICE_LOST_RETRY;
3252 
3253         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3254 
3255         list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
3256         list = kmem_zalloc(list_size, KM_SLEEP);
3257         if (list == NULL) {
3258                 rval = QL_MEMORY_ALLOC_FAILED;
3259                 EL(ha, "failed, rval = %xh\n", rval);
3260                 return (rval);
3261         }
3262 
3263         do {
3264                 /*
3265                  * Get data from RISC code d_id list to init each device queue.
3266                  */
3267                 rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
3268                 if (rval != QL_SUCCESS) {
3269                         kmem_free(list, list_size);
3270                         EL(ha, "failed, rval = %xh\n", rval);
3271                         return (rval);
3272                 }
3273 
3274                 /* Acquire adapter state lock. */
3275                 ADAPTER_STATE_LOCK(ha);
3276 
3277                 /* Mark all queues as unusable. */
3278                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3279                         for (link = ha->dev[index].first; link != NULL;
3280                             link = link->next) {
3281                                 tq = link->base_address;
3282                                 DEVICE_QUEUE_LOCK(tq);
3283                                 if (!(tq->flags & TQF_PLOGI_PROGRS) &&
3284                                     !(ha->topology & QL_N_PORT)) {
3285                                         tq->loop_id = (uint16_t)
3286                                             (tq->loop_id | PORT_LOST_ID);
3287                                 }
3288                                 DEVICE_QUEUE_UNLOCK(tq);
3289                         }
3290                 }
3291 
3292                 /* If device not in queues add new queue. */
3293                 for (index = 0; index < mr.mb[1]; index++) {
3294                         ql_dev_list(ha, list, index, &d_id, &loop_id);
3295 
3296                         if (VALID_DEVICE_ID(ha, loop_id)) {
3297                                 tq = ql_dev_init(ha, d_id, loop_id);
3298                                 if (tq != NULL) {
3299                                         tq->loop_id = loop_id;
3300 
3301                                         /* Test for fabric device. */
3302                                         if (d_id.b.domain !=
3303                                             ha->d_id.b.domain ||
3304                                             d_id.b.area != ha->d_id.b.area) {
3305                                                 tq->flags |= TQF_FABRIC_DEVICE;
3306                                         }
3307 
3308                                         ADAPTER_STATE_UNLOCK(ha);
3309                                         if (ql_get_port_database(ha, tq,
3310                                             PDF_NONE) == QL_SUCCESS) {
3311                                                 ADAPTER_STATE_LOCK(ha);
3312                                                 tq->loop_id = (uint16_t)
3313                                                     (tq->loop_id &
3314                                                     ~PORT_LOST_ID);
3315                                         } else {
3316                                                 ADAPTER_STATE_LOCK(ha);
3317                                         }
3318                                 }
3319                         }
3320                 }
3321 
3322                 /* 24xx does not report switch devices in ID list. */
3323                 if ((CFG_IST(ha, CFG_CTRL_24258081)) &&
3324                     ha->topology & (QL_F_PORT | QL_FL_PORT)) {
3325                         d_id.b24 = 0xfffffe;
3326                         tq = ql_dev_init(ha, d_id, FL_PORT_24XX_HDL);
3327                         if (tq != NULL) {
3328                                 tq->flags |= TQF_FABRIC_DEVICE;
3329                                 ADAPTER_STATE_UNLOCK(ha);
3330                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
3331                                 ADAPTER_STATE_LOCK(ha);
3332                         }
3333                         d_id.b24 = 0xfffffc;
3334                         tq = ql_dev_init(ha, d_id, SNS_24XX_HDL);
3335                         if (tq != NULL) {
3336                                 tq->flags |= TQF_FABRIC_DEVICE;
3337                                 ADAPTER_STATE_UNLOCK(ha);
3338                                 if (ha->vp_index != 0) {
3339                                         (void) ql_login_fport(ha, tq,
3340                                             SNS_24XX_HDL, LFF_NONE, NULL);
3341                                 }
3342                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
3343                                 ADAPTER_STATE_LOCK(ha);
3344                         }
3345                 }
3346 
3347                 /* If F_port exists, allocate queue for FL_Port. */
3348                 index = ql_alpa_to_index[0xfe];
3349                 d_id.b24 = 0;
3350                 if (ha->dev[index].first != NULL) {
3351                         tq = ql_dev_init(ha, d_id, (uint16_t)
3352                             (CFG_IST(ha, CFG_CTRL_24258081) ?
3353                             FL_PORT_24XX_HDL : FL_PORT_LOOP_ID));
3354                         if (tq != NULL) {
3355                                 tq->flags |= TQF_FABRIC_DEVICE;
3356                                 ADAPTER_STATE_UNLOCK(ha);
3357                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
3358                                 ADAPTER_STATE_LOCK(ha);
3359                         }
3360                 }
3361 
3362                 /* Allocate queue for broadcast. */
3363                 d_id.b24 = 0xffffff;
3364                 (void) ql_dev_init(ha, d_id, (uint16_t)
3365                     (CFG_IST(ha, CFG_CTRL_24258081) ? BROADCAST_24XX_HDL :
3366                     IP_BROADCAST_LOOP_ID));
3367 
3368                 /* Check for any devices lost. */
3369                 loop = FALSE;
3370                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3371                         for (link = ha->dev[index].first; link != NULL;
3372                             link = link->next) {
3373                                 tq = link->base_address;
3374 
3375                                 if ((tq->loop_id & PORT_LOST_ID) &&
3376                                     !(tq->flags & (TQF_INITIATOR_DEVICE |
3377                                     TQF_FABRIC_DEVICE))) {
3378                                         loop = TRUE;
3379                                 }
3380                         }
3381                 }
3382 
3383                 /* Release adapter state lock. */
3384                 ADAPTER_STATE_UNLOCK(ha);
3385 
3386                 /* Give devices time to recover. */
3387                 if (loop == TRUE) {
3388                         drv_usecwait(1000000);
3389                 }
3390         } while (retries-- && loop == TRUE &&
3391             !(ha->pha->task_daemon_flags & LOOP_RESYNC_NEEDED));
3392 
3393         kmem_free(list, list_size);
3394 
3395         if (rval != QL_SUCCESS) {
3396                 EL(ha, "failed=%xh\n", rval);
3397         } else {
3398                 /*EMPTY*/
3399                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3400         }
3401 
3402         return (rval);
3403 }
3404 
3405 /*
3406  * ql_dev_list
3407  *      Gets device d_id and loop ID from firmware device list.
3408  *
3409  * Input:
3410  *      ha:     adapter state pointer.
3411  *      list    device list pointer.
3412  *      index:  list index of device data.
3413  *      d_id:   pointer for d_id data.
3414  *      id:     pointer for loop ID.
3415  *
3416  * Context:
3417  *      Kernel context.
3418  */
3419 void
3420 ql_dev_list(ql_adapter_state_t *ha, union ql_dev_id_list *list,
3421     uint32_t index, port_id_t *d_id, uint16_t *id)
3422 {
3423         if (CFG_IST(ha, CFG_CTRL_24258081)) {
3424                 struct ql_24_dev_id     *list24 = (struct ql_24_dev_id *)list;
3425 
3426                 d_id->b.al_pa = list24[index].al_pa;
3427                 d_id->b.area = list24[index].area;
3428                 d_id->b.domain = list24[index].domain;
3429                 *id = CHAR_TO_SHORT(list24[index].n_port_hdl_l,
3430                     list24[index].n_port_hdl_h);
3431 
3432         } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
3433                 struct ql_ex_dev_id     *list23 = (struct ql_ex_dev_id *)list;
3434 
3435                 d_id->b.al_pa = list23[index].al_pa;
3436                 d_id->b.area = list23[index].area;
3437                 d_id->b.domain = list23[index].domain;
3438                 *id = CHAR_TO_SHORT(list23[index].loop_id_l,
3439                     list23[index].loop_id_h);
3440 
3441         } else {
3442                 struct ql_dev_id        *list22 = (struct ql_dev_id *)list;
3443 
3444                 d_id->b.al_pa = list22[index].al_pa;
3445                 d_id->b.area = list22[index].area;
3446                 d_id->b.domain = list22[index].domain;
3447                 *id = (uint16_t)list22[index].loop_id;
3448         }
3449 }
3450 
3451 /*
3452  * ql_configure_fabric
3453  *      Setup fabric context.
3454  *
3455  * Input:
3456  *      ha = adapter state pointer.
3457  *
3458  * Returns:
3459  *      ql local function return status code.
3460  *
3461  * Context:
3462  *      Kernel context.
3463  */
3464 static int
3465 ql_configure_fabric(ql_adapter_state_t *ha)
3466 {
3467         port_id_t       d_id;
3468         ql_tgt_t        *tq;
3469         int             rval = QL_FUNCTION_FAILED;
3470 
3471         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3472 
3473         ha->topology = (uint8_t)(ha->topology & ~QL_SNS_CONNECTION);
3474 
3475         /* Test switch fabric controller present. */
3476         d_id.b24 = FS_FABRIC_F_PORT;
3477         tq = ql_d_id_to_queue(ha, d_id);
3478         if (tq != NULL) {
3479                 /* Get port/node names of F_Port. */
3480                 (void) ql_get_port_database(ha, tq, PDF_NONE);
3481 
3482                 d_id.b24 = FS_NAME_SERVER;
3483                 tq = ql_d_id_to_queue(ha, d_id);
3484                 if (tq != NULL) {
3485                         (void) ql_get_port_database(ha, tq, PDF_NONE);
3486                         ha->topology = (uint8_t)
3487                             (ha->topology | QL_SNS_CONNECTION);
3488                         rval = QL_SUCCESS;
3489                 }
3490         }
3491 
3492         if (rval != QL_SUCCESS) {
3493                 EL(ha, "failed=%xh\n", rval);
3494         } else {
3495                 /*EMPTY*/
3496                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3497         }
3498         return (rval);
3499 }
3500 
3501 /*
3502  * ql_reset_chip
3503  *      Reset ISP chip.
3504  *
3505  * Input:
3506  *      ha = adapter block pointer.
3507  *      All activity on chip must be already stopped.
3508  *      ADAPTER_STATE_LOCK must be released.
3509  *
3510  * Context:
3511  *      Interrupt or Kernel context, no mailbox commands allowed.
3512  */
3513 void
3514 ql_reset_chip(ql_adapter_state_t *vha)
3515 {
3516         uint32_t                cnt;
3517         uint16_t                cmd;
3518         ql_adapter_state_t      *ha = vha->pha;
3519 
3520         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3521 
3522         /*
3523          * accessing pci space while not powered can cause panic's
3524          * on some platforms (i.e. Sunblade 1000's)
3525          */
3526         if (ha->power_level == PM_LEVEL_D3) {
3527                 QL_PRINT_2(CE_CONT, "(%d): Low Power exit\n", ha->instance);
3528                 return;
3529         }
3530 
3531         /* Reset all outbound mailbox registers */
3532         for (cnt = 0; cnt < ha->reg_off->mbox_cnt; cnt++) {
3533                 WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
3534         }
3535 
3536         if (CFG_IST(ha, CFG_CTRL_8021)) {
3537                 ha->timeout_cnt = 0;
3538                 ql_8021_reset_chip(ha);
3539                 QL_PRINT_3(CE_CONT, "(%d): 8021 exit\n", ha->instance);
3540                 return;
3541         }
3542 
3543         /* Disable ISP interrupts. */
3544         WRT16_IO_REG(ha, ictrl, 0);
3545         ADAPTER_STATE_LOCK(ha);
3546         ha->flags &= ~INTERRUPTS_ENABLED;
3547         ADAPTER_STATE_UNLOCK(ha);
3548 
3549         if (CFG_IST(ha, CFG_CTRL_242581)) {
3550                 RD32_IO_REG(ha, ictrl);
3551                 ql_reset_24xx_chip(ha);
3552                 QL_PRINT_3(CE_CONT, "(%d): 24xx exit\n", ha->instance);
3553                 return;
3554         }
3555 
3556         /*
3557          * We are going to reset the chip in case of 2300. That might cause
3558          * a PBM ERR if a DMA transaction is in progress. One way of
3559          * avoiding it is to disable Bus Master operation before we start
3560          * the reset activity.
3561          */
3562         cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3563         cmd = (uint16_t)(cmd & ~PCI_COMM_ME);
3564         ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3565 
3566         /* Pause RISC. */
3567         WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3568         for (cnt = 0; cnt < 30000; cnt++) {
3569                 if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3570                         break;
3571                 }
3572                 drv_usecwait(MILLISEC);
3573         }
3574 
3575         /*
3576          * A call to ql_isr() can still happen through
3577          * ql_mailbox_command(). So Mark that we are/(will-be)
3578          * running from rom code now.
3579          */
3580         TASK_DAEMON_LOCK(ha);
3581         ha->task_daemon_flags &= ~(FIRMWARE_UP | FIRMWARE_LOADED);
3582         TASK_DAEMON_UNLOCK(ha);
3583 
3584         /* Select FPM registers. */
3585         WRT16_IO_REG(ha, ctrl_status, 0x20);
3586 
3587         /* FPM Soft Reset. */
3588         WRT16_IO_REG(ha, fpm_diag_config, 0x100);
3589 
3590         /* Toggle FPM reset for 2300 */
3591         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3592                 WRT16_IO_REG(ha, fpm_diag_config, 0);
3593         }
3594 
3595         /* Select frame buffer registers. */
3596         WRT16_IO_REG(ha, ctrl_status, 0x10);
3597 
3598         /* Reset frame buffer FIFOs. */
3599         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3600                 WRT16_IO_REG(ha, fb_cmd, 0x00fc);
3601                 /* read back fb_cmd until zero or 3 seconds max */
3602                 for (cnt = 0; cnt < 300000; cnt++) {
3603                         if ((RD16_IO_REG(ha, fb_cmd) & 0xff) == 0) {
3604                                 break;
3605                         }
3606                         drv_usecwait(10);
3607                 }
3608         } else  {
3609                 WRT16_IO_REG(ha, fb_cmd, 0xa000);
3610         }
3611 
3612         /* Select RISC module registers. */
3613         WRT16_IO_REG(ha, ctrl_status, 0);
3614 
3615         /* Reset RISC module. */
3616         WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
3617 
3618         /* Reset ISP semaphore. */
3619         WRT16_IO_REG(ha, semaphore, 0);
3620 
3621         /* Release RISC module. */
3622         WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3623 
3624         /* Insure mailbox registers are free. */
3625         WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
3626         WRT16_IO_REG(ha, hccr, HC_CLR_HOST_INT);
3627 
3628         /* clear the mailbox command pointer. */
3629         ql_clear_mcp(ha);
3630 
3631         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3632             ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3633 
3634         /* Bus Master is disabled so chip reset is safe. */
3635         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3636                 WRT16_IO_REG(ha, ctrl_status, ISP_RESET);
3637                 drv_usecwait(MILLISEC);
3638 
3639                 /* Wait for reset to finish. */
3640                 for (cnt = 0; cnt < 30000; cnt++) {
3641                         if ((RD16_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3642                                 break;
3643                         }
3644                         drv_usecwait(MILLISEC);
3645                 }
3646         }
3647 
3648         /* Wait for RISC to recover from reset. */
3649         for (cnt = 0; cnt < 30000; cnt++) {
3650                 if (RD16_IO_REG(ha, mailbox_out[0]) != MBS_BUSY) {
3651                         break;
3652                 }
3653                 drv_usecwait(MILLISEC);
3654         }
3655 
3656         /* restore bus master */
3657         cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3658         cmd = (uint16_t)(cmd | PCI_COMM_ME);
3659         ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3660 
3661         /* Disable RISC pause on FPM parity error. */
3662         WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
3663 
3664         /* Initialize probe registers */
3665         if (CFG_IST(ha, CFG_SBUS_CARD)) {
3666                 /* Pause RISC. */
3667                 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3668                 for (cnt = 0; cnt < 30000; cnt++) {
3669                         if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3670                                 break;
3671                         } else {
3672                                 drv_usecwait(MILLISEC);
3673                         }
3674                 }
3675 
3676                 /* Select FPM registers. */
3677                 WRT16_IO_REG(ha, ctrl_status, 0x30);
3678 
3679                 /* Set probe register */
3680                 WRT16_IO_REG(ha, mailbox_in[23], 0x204c);
3681 
3682                 /* Select RISC module registers. */
3683                 WRT16_IO_REG(ha, ctrl_status, 0);
3684 
3685                 /* Release RISC module. */
3686                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3687         }
3688 
3689         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3690 }
3691 
3692 /*
3693  * ql_reset_24xx_chip
3694  *      Reset ISP24xx chip.
3695  *
3696  * Input:
3697  *      ha = adapter block pointer.
3698  *      All activity on chip must be already stopped.
3699  *
3700  * Context:
3701  *      Interrupt or Kernel context, no mailbox commands allowed.
3702  */
3703 void
3704 ql_reset_24xx_chip(ql_adapter_state_t *ha)
3705 {
3706         uint32_t        timer, stat;
3707 
3708         /* Shutdown DMA. */
3709         WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN | MWB_4096_BYTES);
3710 
3711         /* Wait for DMA to stop. */
3712         for (timer = 0; timer < 30000; timer++) {
3713                 if ((RD32_IO_REG(ha, ctrl_status) & DMA_ACTIVE) == 0) {
3714                         break;
3715                 }
3716                 drv_usecwait(100);
3717         }
3718 
3719         /* Stop the firmware. */
3720         WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3721         WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
3722         WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
3723         for (timer = 0; timer < 30000; timer++) {
3724                 stat = RD32_IO_REG(ha, risc2host);
3725                 if (stat & BIT_15) {
3726                         if ((stat & 0xff) < 0x12) {
3727                                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3728                                 break;
3729                         }
3730                         WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3731                 }
3732                 drv_usecwait(100);
3733         }
3734 
3735         /* Reset the chip. */
3736         WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
3737             MWB_4096_BYTES);
3738         drv_usecwait(100);
3739 
3740         /* Wait for idle status from ROM firmware. */
3741         for (timer = 0; timer < 30000; timer++) {
3742                 if (RD16_IO_REG(ha, mailbox_out[0]) == 0) {
3743                         break;
3744                 }
3745                 drv_usecwait(100);
3746         }
3747 
3748         /* Wait for reset to finish. */
3749         for (timer = 0; timer < 30000; timer++) {
3750                 if ((RD32_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3751                         break;
3752                 }
3753                 drv_usecwait(100);
3754         }
3755 
3756         /* clear the mailbox command pointer. */
3757         ql_clear_mcp(ha);
3758 
3759         /* Insure mailbox registers are free. */
3760         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3761             ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3762 
3763         if (ha->flags & MPI_RESET_NEEDED) {
3764                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3765                 WRT16_IO_REG(ha, mailbox_in[0], MBC_RESTART_MPI);
3766                 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
3767                 for (timer = 0; timer < 30000; timer++) {
3768                         stat = RD32_IO_REG(ha, risc2host);
3769                         if (stat & BIT_15) {
3770                                 if ((stat & 0xff) < 0x12) {
3771                                         WRT32_IO_REG(ha, hccr,
3772                                             HC24_CLR_RISC_INT);
3773                                         break;
3774                                 }
3775                                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3776                         }
3777                         drv_usecwait(100);
3778                 }
3779                 ADAPTER_STATE_LOCK(ha);
3780                 ha->flags &= ~MPI_RESET_NEEDED;
3781                 ADAPTER_STATE_UNLOCK(ha);
3782         }
3783 
3784         /*
3785          * Set flash write-protection.
3786          */
3787         if ((ha->flags & ONLINE) == 0) {
3788                 ql_24xx_protect_flash(ha);
3789         }
3790 }
3791 
3792 /*
3793  * ql_clear_mcp
3794  *      Carefully clear the mailbox command pointer in the ha struct.
3795  *
3796  * Input:
3797  *      ha = adapter block pointer.
3798  *
3799  * Context:
3800  *      Interrupt or Kernel context, no mailbox commands allowed.
3801  */
3802 
3803 static void
3804 ql_clear_mcp(ql_adapter_state_t *ha)
3805 {
3806         uint32_t cnt;
3807 
3808         /* Don't null ha->mcp without the lock, but don't hang either. */
3809         if (MBX_REGISTER_LOCK_OWNER(ha) == curthread) {
3810                 ha->mcp = NULL;
3811         } else {
3812                 for (cnt = 0; cnt < 300000; cnt++) {
3813                         if (TRY_MBX_REGISTER_LOCK(ha) != 0) {
3814                                 ha->mcp = NULL;
3815                                 MBX_REGISTER_UNLOCK(ha);
3816                                 break;
3817                         } else {
3818                                 drv_usecwait(10);
3819                         }
3820                 }
3821         }
3822 }
3823 
3824 
3825 /*
3826  * ql_abort_isp
3827  *      Resets ISP and aborts all outstanding commands.
3828  *
3829  * Input:
3830  *      ha = adapter state pointer.
3831  *      DEVICE_QUEUE_LOCK must be released.
3832  *
3833  * Returns:
3834  *      ql local function return status code.
3835  *
3836  * Context:
3837  *      Kernel context.
3838  */
3839 int
3840 ql_abort_isp(ql_adapter_state_t *vha)
3841 {
3842         ql_link_t               *link, *link2;
3843         ddi_devstate_t          state;
3844         uint16_t                index;
3845         ql_tgt_t                *tq;
3846         ql_lun_t                *lq;
3847         ql_srb_t                *sp;
3848         int                     rval = QL_SUCCESS;
3849         ql_adapter_state_t      *ha = vha->pha;
3850 
3851         QL_PRINT_2(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3852 
3853         TASK_DAEMON_LOCK(ha);
3854         ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
3855         if (ha->task_daemon_flags & ABORT_ISP_ACTIVE ||
3856             (ha->flags & ONLINE) == 0 || ha->flags & ADAPTER_SUSPENDED) {
3857                 TASK_DAEMON_UNLOCK(ha);
3858                 return (rval);
3859         }
3860 
3861         ha->task_daemon_flags |= ABORT_ISP_ACTIVE;
3862         ha->task_daemon_flags &= ~(RESET_MARKER_NEEDED | FIRMWARE_UP |
3863             FIRMWARE_LOADED);
3864         for (vha = ha; vha != NULL; vha = vha->vp_next) {
3865                 vha->task_daemon_flags |= LOOP_DOWN;
3866                 vha->task_daemon_flags &= ~(COMMAND_WAIT_NEEDED |
3867                     LOOP_RESYNC_NEEDED);
3868         }
3869 
3870         TASK_DAEMON_UNLOCK(ha);
3871 
3872         if (ha->mailbox_flags & MBX_BUSY_FLG) {
3873                 /* Acquire mailbox register lock. */
3874                 MBX_REGISTER_LOCK(ha);
3875 
3876                 /* Wake up mailbox box routine. */
3877                 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_ABORT);
3878                 cv_broadcast(&ha->cv_mbx_intr);
3879 
3880                 /* Release mailbox register lock. */
3881                 MBX_REGISTER_UNLOCK(ha);
3882 
3883                 /* Wait for mailbox. */
3884                 for (index = 100; index &&
3885                     ha->mailbox_flags & MBX_ABORT; index--) {
3886                         drv_usecwait(50000);
3887                 }
3888         }
3889 
3890         /* Wait for commands to end gracefully if not in panic. */
3891         if (ha->flags & PARITY_ERROR) {
3892                 ADAPTER_STATE_LOCK(ha);
3893                 ha->flags &= ~PARITY_ERROR;
3894                 ADAPTER_STATE_UNLOCK(ha);
3895         } else if (ddi_in_panic() == 0) {
3896                 ql_cmd_wait(ha);
3897         }
3898 
3899         /* Shutdown IP. */
3900         if (ha->flags & IP_INITIALIZED) {
3901                 (void) ql_shutdown_ip(ha);
3902         }
3903 
3904         /* Reset the chip. */
3905         ql_reset_chip(ha);
3906 
3907         /*
3908          * Even though we have waited for outstanding commands to complete,
3909          * except for ones marked SRB_COMMAND_TIMEOUT, and reset the ISP,
3910          * there could still be an interrupt thread active.  The interrupt
3911          * lock will prevent us from getting an sp from the outstanding
3912          * cmds array that the ISR may be using.
3913          */
3914 
3915         /* Place all commands in outstanding cmd list on device queue. */
3916         for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
3917                 REQUEST_RING_LOCK(ha);
3918                 INTR_LOCK(ha);
3919                 if ((link = ha->pending_cmds.first) != NULL) {
3920                         sp = link->base_address;
3921                         ql_remove_link(&ha->pending_cmds, &sp->cmd);
3922 
3923                         REQUEST_RING_UNLOCK(ha);
3924                         index = 0;
3925                 } else {
3926                         REQUEST_RING_UNLOCK(ha);
3927                         if ((sp = ha->outstanding_cmds[index]) == NULL) {
3928                                 INTR_UNLOCK(ha);
3929                                 continue;
3930                         }
3931                 }
3932 
3933                 /*
3934                  * It's not obvious but the index for commands pulled from
3935                  * pending will be zero and that entry in the outstanding array
3936                  * is not used so nulling it is "no harm, no foul".
3937                  */
3938 
3939                 ha->outstanding_cmds[index] = NULL;
3940                 sp->handle = 0;
3941                 sp->flags &= ~SRB_IN_TOKEN_ARRAY;
3942 
3943                 INTR_UNLOCK(ha);
3944 
3945                 /* If command timeout. */
3946                 if (sp->flags & SRB_COMMAND_TIMEOUT) {
3947                         sp->pkt->pkt_reason = CS_TIMEOUT;
3948                         sp->flags &= ~SRB_RETRY;
3949                         sp->flags |= SRB_ISP_COMPLETED;
3950 
3951                         /* Call done routine to handle completion. */
3952                         ql_done(&sp->cmd);
3953                         continue;
3954                 }
3955 
3956                 /* Acquire target queue lock. */
3957                 lq = sp->lun_queue;
3958                 tq = lq->target_queue;
3959                 DEVICE_QUEUE_LOCK(tq);
3960 
3961                 /* Reset watchdog time. */
3962                 sp->wdg_q_time = sp->init_wdg_q_time;
3963 
3964                 /* Place request back on top of device queue. */
3965                 sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED |
3966                     SRB_RETRY);
3967 
3968                 ql_add_link_t(&lq->cmd, &sp->cmd);
3969                 sp->flags |= SRB_IN_DEVICE_QUEUE;
3970 
3971                 /* Release target queue lock. */
3972                 DEVICE_QUEUE_UNLOCK(tq);
3973         }
3974 
3975         /*
3976          * Clear per LUN active count, because there should not be
3977          * any IO outstanding at this time.
3978          */
3979         for (vha = ha; vha != NULL; vha = vha->vp_next) {
3980                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3981                         link = vha->dev[index].first;
3982                         while (link != NULL) {
3983                                 tq = link->base_address;
3984                                 link = link->next;
3985                                 DEVICE_QUEUE_LOCK(tq);
3986                                 tq->outcnt = 0;
3987                                 tq->flags &= ~TQF_QUEUE_SUSPENDED;
3988                                 for (link2 = tq->lun_queues.first;
3989                                     link2 != NULL; link2 = link2->next) {
3990                                         lq = link2->base_address;
3991                                         lq->lun_outcnt = 0;
3992                                         lq->flags &= ~LQF_UNTAGGED_PENDING;
3993                                 }
3994                                 DEVICE_QUEUE_UNLOCK(tq);
3995                         }
3996                 }
3997         }
3998 
3999         if ((rval = ql_check_isp_firmware(ha)) != QL_SUCCESS) {
4000                 if ((rval = ql_chip_diag(ha)) == QL_SUCCESS) {
4001                         rval = ql_load_isp_firmware(ha);
4002                 }
4003         }
4004 
4005         if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
4006             QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS &&
4007             (rval = ql_fw_ready(ha, 10)) == QL_SUCCESS) {
4008 
4009                 /* If reset abort needed that may have been set. */
4010                 TASK_DAEMON_LOCK(ha);
4011                 ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED |
4012                     ABORT_ISP_ACTIVE);
4013                 TASK_DAEMON_UNLOCK(ha);
4014 
4015                 /* Enable ISP interrupts. */
4016                 if (CFG_IST(ha, CFG_CTRL_8021)) {
4017                         ql_8021_enable_intrs(ha);
4018                 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
4019                         WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
4020                 } else {
4021                         WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
4022                 }
4023 
4024                 ADAPTER_STATE_LOCK(ha);
4025                 ha->flags |= INTERRUPTS_ENABLED;
4026                 ADAPTER_STATE_UNLOCK(ha);
4027 
4028                 /* Set loop online, if it really is. */
4029                 ql_loop_online(ha);
4030 
4031                 state = ddi_get_devstate(ha->dip);
4032                 if (state != DDI_DEVSTATE_UP) {
4033                         /*EMPTY*/
4034                         ddi_dev_report_fault(ha->dip, DDI_SERVICE_RESTORED,
4035                             DDI_DEVICE_FAULT, "Device reset succeeded");
4036                 }
4037         } else {
4038                 /* Enable ISP interrupts. */
4039                 if (CFG_IST(ha, CFG_CTRL_8021)) {
4040                         ql_8021_enable_intrs(ha);
4041                 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
4042                         WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
4043                 } else {
4044                         WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
4045                 }
4046 
4047                 ADAPTER_STATE_LOCK(ha);
4048                 ha->flags |= INTERRUPTS_ENABLED;
4049                 ADAPTER_STATE_UNLOCK(ha);
4050 
4051                 TASK_DAEMON_LOCK(ha);
4052                 ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE);
4053                 ha->task_daemon_flags |= LOOP_DOWN;
4054                 TASK_DAEMON_UNLOCK(ha);
4055 
4056                 ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
4057         }
4058 
4059         if (rval != QL_SUCCESS) {
4060                 EL(ha, "failed, rval = %xh\n", rval);
4061         } else {
4062                 /*EMPTY*/
4063                 QL_PRINT_2(CE_CONT, "(%d): done\n", ha->instance);
4064         }
4065         return (rval);
4066 }
4067 
4068 /*
4069  * ql_vport_control
4070  *      Issue Virtual Port Control command.
4071  *
4072  * Input:
4073  *      ha = virtual adapter state pointer.
4074  *      cmd = control command.
4075  *
4076  * Returns:
4077  *      ql local function return status code.
4078  *
4079  * Context:
4080  *      Kernel context.
4081  */
4082 int
4083 ql_vport_control(ql_adapter_state_t *ha, uint8_t cmd)
4084 {
4085         ql_mbx_iocb_t   *pkt;
4086         uint8_t         bit;
4087         int             rval;
4088         uint32_t        pkt_size;
4089 
4090         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
4091 
4092         if (ha->vp_index != 0) {
4093                 pkt_size = sizeof (ql_mbx_iocb_t);
4094                 pkt = kmem_zalloc(pkt_size, KM_SLEEP);
4095                 if (pkt == NULL) {
4096                         EL(ha, "failed, kmem_zalloc\n");
4097                         return (QL_MEMORY_ALLOC_FAILED);
4098                 }
4099 
4100                 pkt->vpc.entry_type = VP_CONTROL_TYPE;
4101                 pkt->vpc.entry_count = 1;
4102                 pkt->vpc.command = cmd;
4103                 pkt->vpc.vp_count = 1;
4104                 bit = (uint8_t)(ha->vp_index - 1);
4105                 pkt->vpc.vp_index[bit / 8] = (uint8_t)
4106                     (pkt->vpc.vp_index[bit / 8] | BIT_0 << bit % 8);
4107 
4108                 rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
4109                 if (rval == QL_SUCCESS && pkt->vpc.status != 0) {
4110                         rval = QL_COMMAND_ERROR;
4111                 }
4112 
4113                 kmem_free(pkt, pkt_size);
4114         } else {
4115                 rval = QL_SUCCESS;
4116         }
4117 
4118         if (rval != QL_SUCCESS) {
4119                 EL(ha, "failed, rval = %xh\n", rval);
4120         } else {
4121                 /*EMPTY*/
4122                 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
4123                     ha->vp_index);
4124         }
4125         return (rval);
4126 }
4127 
4128 /*
4129  * ql_vport_modify
4130  *      Issue of Modify Virtual Port command.
4131  *
4132  * Input:
4133  *      ha = virtual adapter state pointer.
4134  *      cmd = command.
4135  *      opt = option.
4136  *
4137  * Context:
4138  *      Interrupt or Kernel context, no mailbox commands allowed.
4139  */
4140 int
4141 ql_vport_modify(ql_adapter_state_t *ha, uint8_t cmd, uint8_t opt)
4142 {
4143         ql_mbx_iocb_t   *pkt;
4144         int             rval;
4145         uint32_t        pkt_size;
4146 
4147         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
4148 
4149         pkt_size = sizeof (ql_mbx_iocb_t);
4150         pkt = kmem_zalloc(pkt_size, KM_SLEEP);
4151         if (pkt == NULL) {
4152                 EL(ha, "failed, kmem_zalloc\n");
4153                 return (QL_MEMORY_ALLOC_FAILED);
4154         }
4155 
4156         pkt->vpm.entry_type = VP_MODIFY_TYPE;
4157         pkt->vpm.entry_count = 1;
4158         pkt->vpm.command = cmd;
4159         pkt->vpm.vp_count = 1;
4160         pkt->vpm.first_vp_index = ha->vp_index;
4161         pkt->vpm.first_options = opt;
4162         bcopy(ha->loginparams.nport_ww_name.raw_wwn, pkt->vpm.first_port_name,
4163             8);
4164         bcopy(ha->loginparams.node_ww_name.raw_wwn, pkt->vpm.first_node_name,
4165             8);
4166 
4167         rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
4168         if (rval == QL_SUCCESS && pkt->vpm.status != 0) {
4169                 EL(ha, "failed, ql_issue_mbx_iocb=%xh, status=%xh\n", rval,
4170                     pkt->vpm.status);
4171                 rval = QL_COMMAND_ERROR;
4172         }
4173 
4174         kmem_free(pkt, pkt_size);
4175 
4176         if (rval != QL_SUCCESS) {
4177                 EL(ha, "failed, rval = %xh\n", rval);
4178         } else {
4179                 /*EMPTY*/
4180                 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
4181                     ha->vp_index);
4182         }
4183         return (rval);
4184 }
4185 
4186 /*
4187  * ql_vport_enable
4188  *      Enable virtual port.
4189  *
4190  * Input:
4191  *      ha = virtual adapter state pointer.
4192  *
4193  * Context:
4194  *      Kernel context.
4195  */
4196 int
4197 ql_vport_enable(ql_adapter_state_t *ha)
4198 {
4199         int     timer;
4200 
4201         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
4202 
4203         ha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
4204         TASK_DAEMON_LOCK(ha);
4205         ha->task_daemon_flags |= LOOP_DOWN;
4206         ha->task_daemon_flags &= ~(FC_STATE_CHANGE | STATE_ONLINE);
4207         TASK_DAEMON_UNLOCK(ha);
4208 
4209         ADAPTER_STATE_LOCK(ha);
4210         ha->flags |= VP_ENABLED;
4211         ADAPTER_STATE_UNLOCK(ha);
4212 
4213         if (ql_vport_modify(ha, VPM_MODIFY_ENABLE, VPO_TARGET_MODE_DISABLED |
4214             VPO_INITIATOR_MODE_ENABLED | VPO_ENABLED) != QL_SUCCESS) {
4215                 QL_PRINT_2(CE_CONT, "(%d): failed to enable virtual port=%d\n",
4216                     ha->instance, ha->vp_index);
4217                 return (QL_FUNCTION_FAILED);
4218         }
4219         if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
4220                 /* Wait for loop to come up. */
4221                 for (timer = 0; timer < 3000 &&
4222                     !(ha->task_daemon_flags & STATE_ONLINE);
4223                     timer++) {
4224                         delay(1);
4225                 }
4226         }
4227 
4228         QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
4229 
4230         return (QL_SUCCESS);
4231 }
4232 
4233 /*
4234  * ql_vport_create
4235  *      Create virtual port context.
4236  *
4237  * Input:
4238  *      ha:     parent adapter state pointer.
4239  *      index:  virtual port index number.
4240  *
4241  * Context:
4242  *      Kernel context.
4243  */
4244 ql_adapter_state_t *
4245 ql_vport_create(ql_adapter_state_t *ha, uint8_t index)
4246 {
4247         ql_adapter_state_t      *vha;
4248 
4249         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
4250 
4251         /* Inherit the parents data. */
4252         vha = kmem_alloc(sizeof (ql_adapter_state_t), KM_SLEEP);
4253 
4254         ADAPTER_STATE_LOCK(ha);
4255         bcopy(ha, vha, sizeof (ql_adapter_state_t));
4256         vha->pi_attrs = NULL;
4257         vha->ub_outcnt = 0;
4258         vha->ub_allocated = 0;
4259         vha->flags = 0;
4260         vha->task_daemon_flags = 0;
4261         ha->vp_next = vha;
4262         vha->pha = ha;
4263         vha->vp_index = index;
4264         ADAPTER_STATE_UNLOCK(ha);
4265 
4266         vha->hba.next = NULL;
4267         vha->hba.prev = NULL;
4268         vha->hba.base_address = vha;
4269         vha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
4270         vha->dev = kmem_zalloc(sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE,
4271             KM_SLEEP);
4272         vha->ub_array = kmem_zalloc(sizeof (*vha->ub_array) * QL_UB_LIMIT,
4273             KM_SLEEP);
4274 
4275         QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
4276 
4277         return (vha);
4278 }
4279 
4280 /*
4281  * ql_vport_destroy
4282  *      Destroys virtual port context.
4283  *
4284  * Input:
4285  *      ha = virtual adapter state pointer.
4286  *
4287  * Context:
4288  *      Kernel context.
4289  */
4290 void
4291 ql_vport_destroy(ql_adapter_state_t *ha)
4292 {
4293         ql_adapter_state_t      *vha;
4294 
4295         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
4296 
4297         /* Remove port from list. */
4298         ADAPTER_STATE_LOCK(ha);
4299         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
4300                 if (vha->vp_next == ha) {
4301                         vha->vp_next = ha->vp_next;
4302                         break;
4303                 }
4304         }
4305         ADAPTER_STATE_UNLOCK(ha);
4306 
4307         if (ha->ub_array != NULL) {
4308                 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
4309         }
4310         if (ha->dev != NULL) {
4311                 kmem_free(ha->dev, sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE);
4312         }
4313         kmem_free(ha, sizeof (ql_adapter_state_t));
4314 
4315         QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
4316 }
4317 
4318 /*
4319  * ql_mps_reset
4320  *      Reset MPS for FCoE functions.
4321  *
4322  * Input:
4323  *      ha = virtual adapter state pointer.
4324  *
4325  * Context:
4326  *      Kernel context.
4327  */
4328 static void
4329 ql_mps_reset(ql_adapter_state_t *ha)
4330 {
4331         uint32_t        data, dctl = 1000;
4332 
4333         do {
4334                 if (dctl-- == 0 || ql_wrt_risc_ram_word(ha, 0x7c00, 1) !=
4335                     QL_SUCCESS) {
4336                         return;
4337                 }
4338                 if (ql_rd_risc_ram_word(ha, 0x7c00, &data) != QL_SUCCESS) {
4339                         (void) ql_wrt_risc_ram_word(ha, 0x7c00, 0);
4340                         return;
4341                 }
4342         } while (!(data & BIT_0));
4343 
4344         if (ql_rd_risc_ram_word(ha, 0x7A15, &data) == QL_SUCCESS) {
4345                 dctl = (uint16_t)ql_pci_config_get16(ha, 0x54);
4346                 if ((data & 0xe0) != (dctl & 0xe0)) {
4347                         data &= 0xff1f;
4348                         data |= dctl & 0xe0;
4349                         (void) ql_wrt_risc_ram_word(ha, 0x7A15, data);
4350                 }
4351         }
4352         (void) ql_wrt_risc_ram_word(ha, 0x7c00, 0);
4353 }