Print this page
NEX-1890 update oce from source provided by Emulex

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22      -/* Copyright © 2003-2011 Emulex. All rights reserved.  */
       22 +/*
       23 + * Copyright (c) 2009-2012 Emulex. All rights reserved.
       24 + * Use is subject to license terms.
       25 + */
  23   26  
       27 +
       28 +
  24   29  /*
  25   30   * Source file containing the implementation of the Hardware specific
  26   31   * functions
  27   32   */
  28   33  
  29   34  #include <oce_impl.h>
  30   35  #include <oce_stat.h>
  31   36  #include <oce_ioctl.h>
  32   37  
  33   38  static ddi_device_acc_attr_t reg_accattr = {
  34   39          DDI_DEVICE_ATTR_V1,
  35   40          DDI_STRUCTURE_LE_ACC,
  36   41          DDI_STRICTORDER_ACC,
  37   42          DDI_FLAGERR_ACC
  38   43  };
  39   44  
  40   45  extern int oce_destroy_q(struct oce_dev *dev, struct oce_mbx *mbx,
  41      -    size_t req_size, enum qtype qtype);
       46 +    size_t req_size, enum qtype qtype, uint32_t mode);
  42   47  
  43   48  static int
  44   49  oce_map_regs(struct oce_dev *dev)
  45   50  {
  46   51          int ret = 0;
  47   52          off_t bar_size = 0;
  48   53  
  49   54          ASSERT(NULL != dev);
  50   55          ASSERT(NULL != dev->dip);
  51   56  
  52   57          /* get number of supported bars */
  53   58          ret = ddi_dev_nregs(dev->dip, &dev->num_bars);
  54   59          if (ret != DDI_SUCCESS) {
  55   60                  oce_log(dev, CE_WARN, MOD_CONFIG,
  56      -                    "%d: could not retrieve num_bars", MOD_CONFIG);
       61 +                    "Could not retrieve num_bars, ret =0x%x", ret);
  57   62                  return (DDI_FAILURE);
  58   63          }
  59   64  
       65 +        if (LANCER_CHIP(dev)) {
       66 +                /* Doorbells */
       67 +                ret = ddi_dev_regsize(dev->dip, OCE_PCI_LANCER_DB_BAR,
       68 +                    &bar_size);
       69 +                if (ret != DDI_SUCCESS) {
       70 +                        oce_log(dev, CE_WARN, MOD_CONFIG,
       71 +                            "%d Could not get sizeof BAR %d",
       72 +                            ret, OCE_PCI_LANCER_DB_BAR);
       73 +                        return (DDI_FAILURE);
       74 +                }
       75 +
       76 +                ret = ddi_regs_map_setup(dev->dip, OCE_PCI_LANCER_DB_BAR,
       77 +                    &dev->db_addr, 0, 0, &reg_accattr, &dev->db_handle);
       78 +                if (ret != DDI_SUCCESS) {
       79 +                        oce_log(dev, CE_WARN, MOD_CONFIG,
       80 +                            "Could not map bar %d", OCE_PCI_LANCER_DB_BAR);
       81 +                        return (DDI_FAILURE);
       82 +                }
       83 +                return (DDI_SUCCESS);
       84 +        }
       85 +
  60   86          /* verify each bar and map it accordingly */
  61   87          /* PCI CFG */
  62   88          ret = ddi_dev_regsize(dev->dip, OCE_DEV_CFG_BAR, &bar_size);
  63   89          if (ret != DDI_SUCCESS) {
  64   90                  oce_log(dev, CE_WARN, MOD_CONFIG,
  65   91                      "Could not get sizeof BAR %d",
  66   92                      OCE_DEV_CFG_BAR);
  67   93                  return (DDI_FAILURE);
  68   94          }
  69   95  
↓ open down ↓ 50 lines elided ↑ open up ↑
 120  146          return (DDI_SUCCESS);
 121  147  }
 122  148  static void
 123  149  oce_unmap_regs(struct oce_dev *dev)
 124  150  {
 125  151  
 126  152          ASSERT(NULL != dev);
 127  153          ASSERT(NULL != dev->dip);
 128  154  
 129  155          ddi_regs_map_free(&dev->db_handle);
 130      -        ddi_regs_map_free(&dev->csr_handle);
 131      -        ddi_regs_map_free(&dev->dev_cfg_handle);
      156 +        if (!LANCER_CHIP(dev)) {
      157 +                ddi_regs_map_free(&dev->csr_handle);
      158 +                ddi_regs_map_free(&dev->dev_cfg_handle);
      159 +        }
 132  160  
 133  161  }
 134  162  
 135  163  
      164 +static void
      165 +oce_check_slot(struct oce_dev *dev)
      166 +{
      167 +        uint32_t curr = 0;
      168 +        uint32_t max = 0;
      169 +        uint32_t width = 0;
      170 +        uint32_t max_width = 0;
      171 +        uint32_t speed = 0;
      172 +        uint32_t max_speed = 0;
 136  173  
      174 +        curr = OCE_CFG_READ32(dev, PCICFG_PCIE_LINK_STATUS_OFFSET);
 137  175  
      176 +        width = (curr >> PCIE_LINK_STATUS_NEG_WIDTH_SHIFT) &
      177 +            PCIE_LINK_STATUS_NEG_WIDTH_MASK;
      178 +        speed = (curr >> PCIE_LINK_STATUS_SPEED_SHIFT) &
      179 +            PCIE_LINK_STATUS_SPEED_MASK;
 138  180  
      181 +        oce_log(dev, CE_NOTE, MOD_CONFIG, "Reg value %x"
      182 +            " width %d speed %d\n", curr, width,  speed);
      183 +        max = OCE_CFG_READ32(dev, PCICFG_PCIE_LINK_CAP_OFFSET);
      184 +
      185 +        max_width = (max >> PCIE_LINK_CAP_MAX_WIDTH_SHIFT) &
      186 +            PCIE_LINK_CAP_MAX_WIDTH_MASK;
      187 +        max_speed = (max >> PCIE_LINK_CAP_MAX_SPEED_SHIFT) &
      188 +            PCIE_LINK_CAP_MAX_SPEED_MASK;
      189 +        oce_log(dev, CE_NOTE, MOD_CONFIG, "Reg value %x"
      190 +            " max_width %d max_speed %d\n",
      191 +            max, max_width,  max_speed);
      192 +
      193 +        if (width < max_width || speed < max_speed) {
      194 +                        oce_log(dev, CE_NOTE, MOD_CONFIG,
      195 +                            "Found CNA device in a Gen%s x%d PCIe Slot."
      196 +                            "It is recommended to be in a Gen2 x%d slot"
      197 +                            "for best performance\n",
      198 +                            speed < max_speed ? "1" : "2",
      199 +                            width, max_width);
      200 +        }
      201 +}
      202 +
      203 +
 139  204  /*
 140  205   * function to map the device memory
 141  206   *
 142  207   * dev - handle to device private data structure
 143  208   *
 144  209   */
 145  210  int
 146  211  oce_pci_init(struct oce_dev *dev)
 147  212  {
 148  213          int ret = 0;
 149  214  
 150  215          ret = oce_map_regs(dev);
 151  216  
 152  217          if (ret != DDI_SUCCESS) {
 153  218                  return (DDI_FAILURE);
 154  219          }
 155      -        dev->fn =  OCE_PCI_FUNC(dev);
 156      -        if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
 157      -                ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      220 +
      221 +        if (!LANCER_CHIP(dev)) {
      222 +                dev->fn =  OCE_PCI_FUNC(dev);
      223 +                if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) !=
      224 +                    DDI_FM_OK) {
      225 +                        ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      226 +                }
 158  227          }
 159  228  
 160  229          if (ret != DDI_FM_OK) {
 161  230                  oce_pci_fini(dev);
 162  231                  return (DDI_FAILURE);
 163  232          }
 164  233  
      234 +        if (!LANCER_CHIP(dev))
      235 +                oce_check_slot(dev);
      236 +
 165  237          return (DDI_SUCCESS);
 166  238  } /* oce_pci_init */
 167  239  
 168  240  /*
 169  241   * function to free device memory mapping mapped using
 170  242   * oce_pci_init
 171  243   *
 172  244   * dev - handle to device private data
 173  245   */
 174  246  void
 175  247  oce_pci_fini(struct oce_dev *dev)
 176  248  {
 177  249          oce_unmap_regs(dev);
 178  250  } /* oce_pci_fini */
 179  251  
 180      -/*
 181      - * function to read the PCI Bus, Device, and function numbers for the
 182      - * device instance.
 183      - *
 184      - * dev - handle to device private data
 185      - */
 186      -int
 187      -oce_get_bdf(struct oce_dev *dev)
 188      -{
 189      -        pci_regspec_t *pci_rp;
 190      -        uint32_t length;
 191      -        int rc;
 192  252  
 193      -        /* Get "reg" property */
 194      -        rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dev->dip,
 195      -            0, "reg", (int **)&pci_rp, (uint_t *)&length);
 196      -
 197      -        if ((rc != DDI_SUCCESS) ||
 198      -            (length < (sizeof (pci_regspec_t) / sizeof (int)))) {
 199      -                oce_log(dev, CE_WARN, MOD_CONFIG,
 200      -                    "Failed to read \"reg\" property, Status = 0x%x", rc);
 201      -                return (rc);
 202      -        }
 203      -
 204      -        dev->pci_bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
 205      -        dev->pci_device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
 206      -        dev->pci_function = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
 207      -
 208      -        oce_log(dev, CE_NOTE, MOD_CONFIG,
 209      -            "\"reg\" property num=%d, Bus=%d, Device=%d, Function=%d",
 210      -            length, dev->pci_bus, dev->pci_device, dev->pci_function);
 211      -
 212      -        /* Free the memory allocated by ddi_prop_lookup_int_array() */
 213      -        ddi_prop_free(pci_rp);
 214      -        return (rc);
 215      -}
 216      -
 217  253  int
 218  254  oce_identify_hw(struct oce_dev *dev)
 219  255  {
 220  256          int ret = DDI_SUCCESS;
      257 +        uint32_t if_type = 0, sli_intf = 0;
 221  258  
 222  259          dev->vendor_id = pci_config_get16(dev->pci_cfg_handle,
 223  260              PCI_CONF_VENID);
 224  261          dev->device_id = pci_config_get16(dev->pci_cfg_handle,
 225  262              PCI_CONF_DEVID);
 226  263          dev->subsys_id = pci_config_get16(dev->pci_cfg_handle,
 227  264              PCI_CONF_SUBSYSID);
 228  265          dev->subvendor_id = pci_config_get16(dev->pci_cfg_handle,
 229  266              PCI_CONF_SUBVENID);
 230  267  
 231  268          switch (dev->device_id) {
 232  269  
 233  270          case DEVID_TIGERSHARK:
 234  271                  dev->chip_rev = OC_CNA_GEN2;
      272 +                /* BE2 hardware properly supports single tx ring */
      273 +                dev->tx_rings = 1;
 235  274                  break;
 236  275          case DEVID_TOMCAT:
 237  276                  dev->chip_rev = OC_CNA_GEN3;
 238  277                  break;
      278 +        case DEVID_LANCER:
      279 +                sli_intf = pci_config_get32(dev->pci_cfg_handle,
      280 +                    SLI_INTF_REG_OFFSET);
      281 +
      282 +                if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
      283 +                    SLI_INTF_IF_TYPE_SHIFT;
      284 +
      285 +                if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
      286 +                    if_type != 0x02) {
      287 +                        oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
      288 +                            "SLI I/F not Valid or different interface type\n");
      289 +                        ret = DDI_FAILURE;
      290 +                        break;
      291 +                }
      292 +                dev->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
      293 +                    SLI_INTF_FAMILY_SHIFT);
      294 +
      295 +                dev->chip_rev = 0;
      296 +                break;
      297 +
 239  298          default:
 240  299                  dev->chip_rev = 0;
 241  300                  ret = DDI_FAILURE;
 242  301                  break;
 243  302          }
 244  303          return (ret);
 245  304  }
 246  305  
 247  306  
 248  307  /*
↓ open down ↓ 57 lines elided ↑ open up ↑
 306  365          if (soft_rst.bits.soft_reset) {
 307  366                  oce_log(dev, CE_WARN, MOD_CONFIG,
 308  367                      "0x%x soft_reset"
 309  368                      "bit asserted[1]. Reset failed",
 310  369                      soft_rst.dw0);
 311  370                  return (DDI_FAILURE);
 312  371          }
 313  372  
 314  373          return (oce_POST(dev));
 315  374  } /* oce_pci_soft_reset */
      375 +
      376 +
      377 +static int lancer_wait_ready(struct oce_dev *dev)
      378 +{
      379 +        uint32_t sliport_status;
      380 +        int status = 0, i;
      381 +
      382 +        for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
      383 +                sliport_status = OCE_DB_READ32(dev, SLIPORT_STATUS_OFFSET);
      384 +                        if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
      385 +                            DDI_FM_OK) {
      386 +                                ddi_fm_service_impact(dev->dip,
      387 +                                    DDI_SERVICE_DEGRADED);
      388 +                                return (EIO);
      389 +                        }
      390 +                if (sliport_status & SLIPORT_STATUS_RDY_MASK)
      391 +                        break;
      392 +                drv_usecwait(20000);
      393 +        }
      394 +
      395 +        if (i == SLIPORT_READY_TIMEOUT)
      396 +                status = DDI_FAILURE;
      397 +
      398 +        return (status);
      399 +}
      400 +
      401 +static int lancer_test_and_set_rdy_state(struct oce_dev *dev)
      402 +{
      403 +        int status;
      404 +        uint32_t sliport_status, err, reset_needed;
      405 +        status = lancer_wait_ready(dev);
      406 +        if (!status) {
      407 +                sliport_status = OCE_DB_READ32(dev, SLIPORT_STATUS_OFFSET);
      408 +                if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
      409 +                        ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      410 +                        return (EIO);
      411 +                }
      412 +                err = sliport_status & SLIPORT_STATUS_ERR_MASK;
      413 +                reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
      414 +                if (err && reset_needed) {
      415 +                        OCE_DB_WRITE32(dev, SLIPORT_CONTROL_OFFSET,
      416 +                            SLI_PORT_CONTROL_IP_MASK);
      417 +                        if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
      418 +                            DDI_FM_OK) {
      419 +                                ddi_fm_service_impact(dev->dip,
      420 +                                    DDI_SERVICE_DEGRADED);
      421 +                                return (EIO);
      422 +                        }
      423 +                        /* check adapter has corrected the error */
      424 +                        status = lancer_wait_ready(dev);
      425 +                        sliport_status = OCE_DB_READ32(dev,
      426 +                            SLIPORT_STATUS_OFFSET);
      427 +                        if (oce_fm_check_acc_handle(dev, dev->db_handle) !=
      428 +                            DDI_FM_OK) {
      429 +                                ddi_fm_service_impact(dev->dip,
      430 +                                    DDI_SERVICE_DEGRADED);
      431 +                                return (EIO);
      432 +                        }
      433 +                        sliport_status &= (SLIPORT_STATUS_ERR_MASK |
      434 +                            SLIPORT_STATUS_RN_MASK);
      435 +                        if (status || sliport_status)
      436 +                                status = -1;
      437 +                } else if (err || reset_needed) {
      438 +                        status = DDI_FAILURE;
      439 +                }
      440 +        }
      441 +        return (status);
      442 +}
      443 +
 316  444  /*
 317      - * function to trigger a POST on the device
      445 + * function to trigger a POST on the Lancer device
 318  446   *
 319  447   * dev - software handle to the device
 320  448   *
 321  449   */
 322  450  int
 323      -oce_POST(struct oce_dev *dev)
      451 +oce_lancer_POST(struct oce_dev *dev)
 324  452  {
      453 +        int status = 0;
      454 +        int sem = 0;
      455 +        int stage = 0;
      456 +        int timeout = 0;
      457 +
      458 +        status = lancer_test_and_set_rdy_state(dev);
      459 +        if (status != 0)
      460 +                return (DDI_FAILURE);
      461 +
      462 +        do {
      463 +                sem = OCE_DB_READ32(dev, MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET);
      464 +                if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
      465 +                        ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      466 +                        return (EIO);
      467 +                }
      468 +                stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
      469 +
      470 +                if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) &
      471 +                    EP_SEMAPHORE_POST_ERR_MASK) {
      472 +                        oce_log(dev, CE_WARN, MOD_CONFIG,
      473 +                            "POST error; stage=0x%x\n", stage);
      474 +                        return (DDI_FAILURE);
      475 +                } else if (stage != POST_STAGE_ARMFW_READY) {
      476 +                        drv_usecwait(1000);
      477 +                } else {
      478 +                        return (0);
      479 +                }
      480 +        } while (timeout++ < 1000);
      481 +        oce_log(dev, CE_WARN, MOD_CONFIG,
      482 +            "POST timeout; stage=0x%x\n", stage);
      483 +        return (DDI_FAILURE);
      484 +
      485 +} /* oce_lancer_POST */
      486 +
      487 +/*
      488 + * function to trigger a POST on the BE device
      489 + *
      490 + * dev - software handle to the device
      491 + *
      492 + */
      493 +int
      494 +oce_be_POST(struct oce_dev *dev)
      495 +{
 325  496          mpu_ep_semaphore_t post_status;
 326  497          clock_t tmo;
 327  498          clock_t earlier = ddi_get_lbolt();
 328  499  
 329  500          /* read semaphore CSR */
 330  501          post_status.dw0 = OCE_CSR_READ32(dev, MPU_EP_SEMAPHORE);
 331  502          if (oce_fm_check_acc_handle(dev, dev->csr_handle) != DDI_FM_OK) {
 332  503                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
 333  504                  return (DDI_FAILURE);
 334  505          }
↓ open down ↓ 26 lines elided ↑ open up ↑
 361  532                          oce_log(dev, CE_WARN, MOD_CONFIG,
 362  533                              "0x%x POST ERROR!!", post_status.dw0);
 363  534                          return (DDI_FAILURE);
 364  535                  }
 365  536                  if (post_status.bits.stage == POST_STAGE_ARMFW_READY)
 366  537                          return (DDI_SUCCESS);
 367  538  
 368  539                  drv_usecwait(100);
 369  540          }
 370  541          return (DDI_FAILURE);
 371      -} /* oce_POST */
      542 +} /* oce_be_POST */
      543 +
 372  544  /*
      545 + * function to trigger a POST on the device
      546 + *
      547 + * dev - software handle to the device
      548 + *
      549 + */
      550 +int
      551 +oce_POST(struct oce_dev *dev)
      552 +{
      553 +        int ret = 0;
      554 +
      555 +        if (LANCER_CHIP(dev)) {
      556 +                ret = oce_lancer_POST(dev);
      557 +        } else {
      558 +                ret = oce_be_POST(dev);
      559 +        }
      560 +
      561 +        return (ret);
      562 +}
      563 +
      564 +/*
 373  565   * function to modify register access attributes corresponding to the
 374  566   * FM capabilities configured by the user
 375  567   *
 376  568   * fm_caps - fm capability configured by the user and accepted by the driver
 377  569   */
 378  570  void
 379  571  oce_set_reg_fma_flags(int fm_caps)
 380  572  {
 381  573          if (fm_caps == DDI_FM_NOT_CAPABLE) {
 382  574                  return;
 383  575          }
 384  576          if (DDI_FM_ACC_ERR_CAP(fm_caps)) {
 385  577                  reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
 386  578          } else {
 387  579                  reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
 388  580          }
 389  581  } /* oce_set_fma_flags */
 390  582  
 391  583  
 392  584  int
 393      -oce_create_nw_interface(struct oce_dev *dev)
      585 +oce_create_nw_interface(struct oce_dev *dev, oce_group_t *grp, uint32_t mode)
 394  586  {
 395  587          int ret;
 396      -        uint32_t capab_flags = OCE_CAPAB_FLAGS;
 397      -        uint32_t capab_en_flags = OCE_CAPAB_ENABLE;
      588 +        uint32_t cap_flags, en_flags;
 398  589  
 399      -        if (dev->rss_enable) {
 400      -                capab_flags |= MBX_RX_IFACE_FLAGS_RSS;
 401      -                capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
      590 +        cap_flags = MBX_RX_IFACE_FLAGS_UNTAGGED;
      591 +        en_flags = MBX_RX_IFACE_FLAGS_UNTAGGED;
      592 +
      593 +        /* first/default group receives broadcast and mcast pkts */
      594 +        if (grp->grp_num == 0) {
      595 +                cap_flags |= MBX_RX_IFACE_FLAGS_BROADCAST |
      596 +                    MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS |
      597 +                    MBX_RX_IFACE_FLAGS_PROMISCUOUS |
      598 +                    MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS |
      599 +                    MBX_RX_IFACE_FLAGS_MCAST;
      600 +
      601 +                en_flags |= MBX_RX_IFACE_FLAGS_BROADCAST |
      602 +                    MBX_RX_IFACE_FLAGS_MCAST;
      603 +
      604 +
      605 +                cap_flags |= MBX_RX_IFACE_FLAGS_PASS_L3L4;
      606 +                en_flags  |= MBX_RX_IFACE_FLAGS_PASS_L3L4;
      607 +                if (grp->rss_enable) {
      608 +                        cap_flags |= MBX_RX_IFACE_FLAGS_RSS;
      609 +                        en_flags |= MBX_RX_IFACE_FLAGS_RSS;
      610 +                }
 402  611          }
 403  612  
 404      -        /* create an interface for the device with out mac */
 405      -        ret = oce_if_create(dev, capab_flags, capab_en_flags,
 406      -            0, &dev->mac_addr[0], (uint32_t *)&dev->if_id);
      613 +        if (grp->grp_num == 0) {
      614 +                ret = oce_if_create(dev, cap_flags, en_flags,
      615 +                    0, NULL,
      616 +                    (uint32_t *)&grp->if_id, mode);
      617 +                /* copy default if_id into dev */
      618 +                dev->if_id = grp->if_id;
      619 +
      620 +        } else {
      621 +                ret = oce_if_create(dev, cap_flags, en_flags,
      622 +                    0, NULL, (uint32_t *)&grp->if_id, mode);
      623 +        }
 407  624          if (ret != 0) {
 408  625                  oce_log(dev, CE_WARN, MOD_CONFIG,
 409      -                    "Interface creation failed: 0x%x", ret);
      626 +                    "Interface creation failed for group "
      627 +                    "instance %d: 0x%x", grp->grp_num, ret);
 410  628                  return (ret);
 411  629          }
 412      -        atomic_inc_32(&dev->nifs);
 413  630  
 414      -        dev->if_cap_flags = capab_en_flags;
 415      -
 416  631          /* Enable VLAN Promisc on HW */
 417      -        ret = oce_config_vlan(dev, (uint8_t)dev->if_id, NULL, 0,
 418      -            B_TRUE, B_TRUE);
      632 +        ret = oce_config_vlan(dev, (uint8_t)grp->if_id,
      633 +            NULL, 0, B_TRUE, B_TRUE, mode);
 419  634          if (ret != 0) {
 420  635                  oce_log(dev, CE_WARN, MOD_CONFIG,
 421      -                    "Config vlan failed: %d", ret);
 422      -                oce_delete_nw_interface(dev);
      636 +                    "Config vlan failed: 0x%x", ret);
      637 +                oce_delete_nw_interface(dev, grp, mode);
 423  638                  return (ret);
 424      -
 425  639          }
 426      -
 427      -        /* set default flow control */
 428      -        ret = oce_set_flow_control(dev, dev->flow_control);
 429      -        if (ret != 0) {
 430      -                oce_log(dev, CE_NOTE, MOD_CONFIG,
 431      -                    "Set flow control failed: %d", ret);
 432      -        }
 433      -        ret = oce_set_promiscuous(dev, dev->promisc);
 434      -
 435      -        if (ret != 0) {
 436      -                oce_log(dev, CE_NOTE, MOD_CONFIG,
 437      -                    "Set Promisc failed: %d", ret);
 438      -        }
 439      -
 440  640          return (0);
 441  641  }
 442  642  
 443  643  void
 444      -oce_delete_nw_interface(struct oce_dev *dev) {
 445      -
 446      -        /* currently only single interface is implmeneted */
 447      -        if (dev->nifs > 0) {
 448      -                (void) oce_if_del(dev, dev->if_id);
 449      -                atomic_dec_32(&dev->nifs);
 450      -        }
 451      -}
 452      -
 453      -static void
 454      -oce_create_itbl(struct oce_dev *dev, char *itbl)
      644 +oce_delete_nw_interface(struct oce_dev *dev, oce_group_t *grp, uint32_t mode)
 455  645  {
 456      -        int i;
 457      -        struct oce_rq **rss_queuep = &dev->rq[1];
 458      -        int nrss  = dev->nrqs - 1;
 459      -        /* fill the indirection table rq 0 is default queue */
 460      -        for (i = 0; i < OCE_ITBL_SIZE; i++) {
 461      -                itbl[i] = rss_queuep[i % nrss]->rss_cpuid;
 462      -        }
 463      -}
      646 +        char itbl[OCE_ITBL_SIZE] = {0};
      647 +        char hkey[OCE_HKEY_SIZE] = {0};
      648 +        int ret = 0;
 464  649  
 465      -int
 466      -oce_setup_adapter(struct oce_dev *dev)
 467      -{
 468      -        int ret;
 469      -        char itbl[OCE_ITBL_SIZE];
 470      -        char hkey[OCE_HKEY_SIZE];
      650 +        if (grp->rss_enable) {
      651 +                ret = oce_config_rss(dev, grp->if_id, hkey,
      652 +                    itbl, OCE_ITBL_SIZE, RSS_ENABLE_NONE, B_FALSE, mode);
 471  653  
 472      -        /* disable the interrupts here and enable in start */
 473      -        oce_chip_di(dev);
 474      -
 475      -        ret = oce_create_nw_interface(dev);
 476      -        if (ret != DDI_SUCCESS) {
 477      -                return (DDI_FAILURE);
 478      -        }
 479      -        ret = oce_create_queues(dev);
 480      -        if (ret != DDI_SUCCESS) {
 481      -                oce_delete_nw_interface(dev);
 482      -                return (DDI_FAILURE);
 483      -        }
 484      -        if (dev->rss_enable) {
 485      -                (void) oce_create_itbl(dev, itbl);
 486      -                (void) oce_gen_hkey(hkey, OCE_HKEY_SIZE);
 487      -                ret = oce_config_rss(dev, dev->if_id, hkey, itbl, OCE_ITBL_SIZE,
 488      -                    OCE_DEFAULT_RSS_TYPE, B_TRUE);
 489  654                  if (ret != DDI_SUCCESS) {
 490      -                        oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 491      -                            "Failed to Configure RSS");
 492      -                        oce_delete_queues(dev);
 493      -                        oce_delete_nw_interface(dev);
 494      -                        return (ret);
      655 +                        oce_log(dev, CE_NOTE, MOD_CONFIG,
      656 +                            "Failed to Disable RSS if_id=%d, ret=0x%x",
      657 +                            grp->if_id, ret);
 495  658                  }
 496  659          }
 497      -        ret = oce_setup_handlers(dev);
 498      -        if (ret != DDI_SUCCESS) {
 499      -                oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 500      -                    "Failed to Setup handlers");
 501      -                oce_delete_queues(dev);
 502      -                oce_delete_nw_interface(dev);
 503      -                return (ret);
 504      -        }
 505      -        return (DDI_SUCCESS);
      660 +        ret = oce_if_del(dev, (uint8_t)grp->if_id, mode);
      661 +        if (ret != DDI_SUCCESS)
      662 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
      663 +                    "Failed to delete nw i/f gidx =%d if_id = 0x%x ret=0x%x",
      664 +                    grp->grp_num, grp->if_id, ret);
 506  665  }
 507  666  
 508  667  void
 509      -oce_unsetup_adapter(struct oce_dev *dev)
      668 +oce_group_create_itbl(oce_group_t *grp, char *itbl)
 510  669  {
 511      -        oce_remove_handler(dev);
 512      -        if (dev->rss_enable) {
 513      -                char itbl[OCE_ITBL_SIZE] = {0};
 514      -                char hkey[OCE_HKEY_SIZE] = {0};
 515      -                int ret = 0;
 516      -
 517      -                ret = oce_config_rss(dev, dev->if_id, hkey, itbl, OCE_ITBL_SIZE,
 518      -                    RSS_ENABLE_NONE, B_TRUE);
 519      -
 520      -                if (ret != DDI_SUCCESS) {
 521      -                        oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 522      -                            "Failed to Disable RSS");
 523      -                }
      670 +        int i;
      671 +        oce_ring_t *rss_queuep = &grp->ring[1];
      672 +        /* fill the indirection table rq 0 is default queue */
      673 +        for (i = 0; i < OCE_ITBL_SIZE; i++) {
      674 +                itbl[i] = rss_queuep[i % (grp->num_rings - 1)].rx->rss_cpuid;
 524  675          }
 525      -        oce_delete_queues(dev);
 526      -        oce_delete_nw_interface(dev);
 527  676  }
 528  677  
      678 +
 529  679  int
 530  680  oce_hw_init(struct oce_dev *dev)
 531  681  {
 532  682          int  ret;
 533  683          struct mac_address_format mac_addr;
 534  684  
 535  685          ret = oce_POST(dev);
 536  686          if (ret != DDI_SUCCESS) {
 537  687                  oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 538  688                      "!!!HW POST1 FAILED");
 539  689                  /* ADD FM FAULT */
 540  690                  return (DDI_FAILURE);
 541  691          }
 542  692          /* create bootstrap mailbox */
 543      -        dev->bmbx = oce_alloc_dma_buffer(dev,
 544      -            sizeof (struct oce_bmbx), NULL, DDI_DMA_CONSISTENT);
 545      -        if (dev->bmbx == NULL) {
      693 +        ret = oce_alloc_dma_buffer(dev, &dev->bmbx,
      694 +            sizeof (struct oce_bmbx), NULL, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
      695 +        if (ret != DDI_SUCCESS) {
 546  696                  oce_log(dev, CE_WARN, MOD_CONFIG,
 547      -                    "Failed to allocate bmbx: size = %u",
 548      -                    (uint32_t)sizeof (struct oce_bmbx));
      697 +                    "Failed to allocate bmbx: 0x%x", ret);
 549  698                  return (DDI_FAILURE);
 550  699          }
 551  700  
 552  701          ret = oce_reset_fun(dev);
 553  702          if (ret != 0) {
 554  703                  oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 555  704                      "!!!FUNCTION RESET FAILED");
 556  705                  goto init_fail;
 557  706          }
 558  707  
 559  708          /* reset the Endianess of BMBX */
 560  709          ret = oce_mbox_init(dev);
 561  710          if (ret != 0) {
 562  711                  oce_log(dev, CE_WARN, MOD_CONFIG,
 563      -                    "Mailbox initialization2 Failed with %d", ret);
      712 +                    "Mailbox initialization failed with 0x%x", ret);
 564  713                  goto init_fail;
 565  714          }
 566  715  
 567  716          /* read the firmware version */
 568      -        ret = oce_get_fw_version(dev);
      717 +        ret = oce_get_fw_version(dev, MBX_BOOTSTRAP);
 569  718          if (ret != 0) {
 570  719                  oce_log(dev, CE_WARN, MOD_CONFIG,
 571      -                    "Firmaware version read failed with %d", ret);
      720 +                    "Firmaware version read failed with 0x%x", ret);
 572  721                  goto init_fail;
 573  722          }
 574  723  
 575  724          /* read the fw config */
 576      -        ret = oce_get_fw_config(dev);
      725 +        ret = oce_get_fw_config(dev, MBX_BOOTSTRAP);
 577  726          if (ret != 0) {
 578  727                  oce_log(dev, CE_WARN, MOD_CONFIG,
 579  728                      "Firmware configuration read failed with %d", ret);
 580  729                  goto init_fail;
 581  730          }
 582  731  
 583  732          /* read the Factory MAC address */
 584  733          ret = oce_read_mac_addr(dev, 0, 1,
 585      -            MAC_ADDRESS_TYPE_NETWORK, &mac_addr);
      734 +            MAC_ADDRESS_TYPE_NETWORK, &mac_addr, MBX_BOOTSTRAP);
 586  735          if (ret != 0) {
 587  736                  oce_log(dev, CE_WARN, MOD_CONFIG,
 588      -                    "MAC address read failed with %d", ret);
      737 +                    "MAC address read failed with 0x%x", ret);
 589  738                  goto init_fail;
 590  739          }
 591  740          bcopy(&mac_addr.mac_addr[0], &dev->mac_addr[0], ETHERADDRL);
      741 +
      742 +        if (!LANCER_CHIP(dev)) {
      743 +                /* cache the ue mask registers for ue detection */
      744 +                dev->ue_mask_lo = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_LO_MASK);
      745 +                dev->ue_mask_hi = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_HI_MASK);
      746 +        }
      747 +
 592  748          return (DDI_SUCCESS);
 593  749  init_fail:
 594  750          oce_hw_fini(dev);
 595  751          return (DDI_FAILURE);
 596  752  }
 597  753  void
 598  754  oce_hw_fini(struct oce_dev *dev)
 599  755  {
 600      -        if (dev->bmbx != NULL) {
 601      -                oce_free_dma_buffer(dev, dev->bmbx);
 602      -                dev->bmbx = NULL;
      756 +        (void) oce_mbox_fini(dev);
      757 +        oce_free_dma_buffer(dev, &dev->bmbx);
      758 +}
      759 +
      760 +boolean_t
      761 +oce_check_ue(struct oce_dev *dev)
      762 +{
      763 +        uint32_t ue_lo;
      764 +        uint32_t ue_hi;
      765 +
      766 +        /* check for  the Hardware unexpected error */
      767 +        ue_lo = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_LO);
      768 +        ue_hi = OCE_CFG_READ32(dev, PCICFG_UE_STATUS_HI);
      769 +
      770 +        if ((~dev->ue_mask_lo & ue_lo) ||
      771 +            (~dev->ue_mask_hi & ue_hi)) {
      772 +                /* Unrecoverable error detected */
      773 +                oce_log(dev, CE_WARN, MOD_CONFIG,
      774 +                    "Hardware UE Detected: "
      775 +                    "UE_LOW:%08x"
      776 +                    "UE_HI:%08x "
      777 +                    "UE_MASK_LO:%08x "
      778 +                    "UE_MASK_HI:%08x",
      779 +                    ue_lo, ue_hi,
      780 +                    dev->ue_mask_lo,
      781 +                    dev->ue_mask_hi);
      782 +                return (B_TRUE);
 603  783          }
      784 +        return (B_FALSE);
 604  785  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX