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_main.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.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  
  24   27  
       28 +
  25   29  /*
  26   30   * Source file containing the implementation of the driver entry points
  27   31   * and related helper functions
  28   32   */
  29   33  
  30   34  #include <oce_impl.h>
  31   35  #include <oce_stat.h>
  32   36  #include <oce_ioctl.h>
  33   37  
  34      -#define ATTACH_DEV_INIT         0x1
  35      -#define ATTACH_FM_INIT          0x2
  36      -#define ATTACH_PCI_CFG          0x4
  37      -#define ATTACH_LOCK_INIT        0x8
  38      -#define ATTACH_PCI_INIT         0x10
  39      -#define ATTACH_HW_INIT          0x20
  40      -#define ATTACH_SETUP_TXRX       0x40
  41      -#define ATTACH_SETUP_ADAP       0x80
  42      -#define ATTACH_SETUP_INTR       0x100
  43      -#define ATTACH_STAT_INIT        0x200
  44      -#define ATTACH_MAC_REG          0x400
  45      -
  46   38  /* ---[ globals and externs ]-------------------------------------------- */
  47   39  const char oce_ident_string[] = OCE_IDENT_STRING;
  48   40  const char oce_mod_name[] = OCE_MOD_NAME;
  49      -struct oce_dev *oce_dev_list[MAX_DEVS + 1];     /* Last entry is invalid */
  50   41  
  51   42  /* driver properties */
       43 +static const char tx_reclaim[]           = "tx_reclaim";
  52   44  static const char flow_control[]         = "flow_control";
  53   45  static const char mtu_prop_name[]        = "oce_default_mtu";
  54   46  static const char tx_ring_size_name[]    = "tx_ring_size";
  55   47  static const char tx_bcopy_limit_name[]  = "tx_bcopy_limit";
  56   48  static const char rx_bcopy_limit_name[]  = "rx_bcopy_limit";
  57   49  static const char rx_frag_size_name[]    = "rx_frag_size";
  58   50  static const char rx_max_bufs_name[]     = "rx_max_bufs";
  59   51  static const char fm_cap_name[]          = "oce_fm_capability";
  60   52  static const char log_level_name[]       = "oce_log_level";
  61   53  static const char lso_capable_name[]     = "lso_capable";
  62   54  static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr";
  63   55  static const char tx_reclaim_threshold_name[] = "tx_reclaim_threshold";
  64      -static const char rx_rings_name[]        = "max_rx_rings";
  65      -static const char tx_rings_name[]        = "max_tx_rings";
       56 +static const char rx_rings_name[] = "max_rx_rings";
       57 +static const char rx_group_name[] = "max_rx_rings_per_group";
       58 +static const char tx_rings_name[] = "max_tx_rings";
  66   59  
  67   60  /* --[ static function prototypes here ]------------------------------- */
  68   61  static int oce_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd);
  69   62  static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  70   63  static int oce_quiesce(dev_info_t *dip);
  71   64  static int oce_suspend(dev_info_t *dip);
  72   65  static int oce_resume(dev_info_t *dip);
  73   66  static void oce_unconfigure(struct oce_dev *dev);
  74   67  static void oce_init_locks(struct oce_dev *dev);
  75   68  static void oce_destroy_locks(struct oce_dev *dev);
  76   69  static void oce_get_params(struct oce_dev *dev);
  77   70  static int oce_get_prop(struct oce_dev *dev, char *propname, int minval,
  78   71      int maxval, int defval, uint32_t *values);
       72 +static void oce_reset_wd_timer(struct oce_dev *dev);
       73 +static void oce_wd_timer(void *arg);
       74 +static void oce_set_wd_timer(struct oce_dev *dev);
       75 +int oce_alloc_queues(struct oce_dev *dev);
       76 +void oce_free_queues(struct oce_dev *dev);
  79   77  
  80   78  static struct cb_ops oce_cb_ops = {
  81   79          nulldev,                /* cb_open */
  82   80          nulldev,                /* cb_close */
  83   81          nodev,                  /* cb_strategy */
  84   82          nodev,                  /* cb_print */
  85   83          nodev,                  /* cb_dump */
  86   84          nodev,                  /* cb_read */
  87   85          nodev,                  /* cb_write */
  88   86          nodev,                  /* cb_ioctl */
↓ open down ↓ 27 lines elided ↑ open up ↑
 116  114  static struct modldrv oce_drv = {
 117  115          &mod_driverops, /* Type of module.  This one is a driver */
 118  116          (char *)oce_ident_string, /* Description string */
 119  117          &oce_dev_ops,   /* driver ops */
 120  118  };
 121  119  
 122  120  static struct modlinkage oce_mod_linkage = {
 123  121          MODREV_1, &oce_drv, NULL
 124  122  };
 125  123  
 126      -#define OCE_M_CB_FLAGS  (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | \
 127      -    MC_PROPINFO)
      124 +#define OCE_M_CB_FLAGS  (MC_IOCTL | MC_GETCAPAB | MC_PROPERTIES)
 128  125  static mac_callbacks_t oce_mac_cb = {
 129  126          OCE_M_CB_FLAGS,         /* mc_callbacks */
 130  127          oce_m_stat,             /* mc_getstat */
 131  128          oce_m_start,            /* mc_start */
 132  129          oce_m_stop,             /* mc_stop */
 133  130          oce_m_promiscuous,      /* mc_setpromisc */
 134  131          oce_m_multicast,        /* mc_multicast */
 135      -        oce_m_unicast,          /* mc_unicast */
 136      -        oce_m_send,             /* mc_tx */
      132 +        NULL,                   /* mc_unicast */
      133 +        NULL,                   /* mc_tx */
 137  134          NULL,                   /* mc_reserve */
 138  135          oce_m_ioctl,            /* mc_ioctl */
 139  136          oce_m_getcap,           /* mc_getcapab */
 140  137          NULL,                   /* open */
 141  138          NULL,                   /* close */
 142  139          oce_m_setprop,          /* set properties */
 143  140          oce_m_getprop,          /* get properties */
 144  141          oce_m_propinfo          /* properties info */
 145  142  };
 146  143  
 147      -extern char *oce_priv_props[];
 148  144  
      145 +/* array of properties supported by this driver */
      146 +char *oce_priv_props[] = {
      147 +        "_tx_rings",
      148 +        "_tx_ring_size",
      149 +        "_tx_bcopy_limit",
      150 +        "_tx_reclaim_threshold",
      151 +        "_rx_rings",
      152 +        "_rx_rings_per_group",
      153 +        "_rx_ring_size",
      154 +        "_rx_bcopy_limit",
      155 +        "_rx_pkts_per_intr",
      156 +        "_log_level",
      157 +        NULL
      158 +};
      159 +
      160 +int oce_irm_enable = -1;
      161 +
      162 +extern int oce_cbfunc(dev_info_t *dip, ddi_cb_action_t cbaction, void *cbarg,
      163 +    void *arg1, void *arg2);
      164 +
 149  165  /* Module Init */
 150  166  int
 151  167  _info(struct modinfo *modinfop)
 152  168  {
 153  169          return (mod_info(&oce_mod_linkage, modinfop));
 154  170  } /* _info */
 155  171  
 156  172  int
 157  173  _init(void)
 158  174  {
 159  175          int ret = 0;
 160  176  
 161  177          /* install the module */
 162      -        mac_init_ops(&oce_dev_ops, "oce");
      178 +        mac_init_ops(&oce_dev_ops, OCE_MOD_NAME);
 163  179  
 164  180          ret = mod_install(&oce_mod_linkage);
 165  181          if (ret) {
 166  182                  cmn_err(CE_WARN, "mod_install failed  rval=%x", ret);
 167  183          }
 168  184  
 169  185          return (ret);
 170  186  } /* _init */
 171  187  
 172  188  
 173  189  int
 174  190  _fini(void)
 175  191  {
 176  192          int ret = 0;
      193 +
 177  194          /* remove the module */
 178  195          ret = mod_remove(&oce_mod_linkage);
 179  196          if (ret != 0) {
 180  197                  return (ret);
 181  198          }
 182  199  
 183  200          mac_fini_ops(&oce_dev_ops);
 184  201  
 185  202          return (ret);
 186  203  } /* _fini */
 187  204  
 188  205  
 189  206  static int
 190  207  oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 191  208  {
 192  209          int ret = 0;
 193  210          struct oce_dev *dev = NULL;
 194  211          mac_register_t *mac;
 195      -        uint8_t dev_index = 0;
 196  212  
 197  213          switch (cmd) {
 198  214          case DDI_RESUME:
 199  215                  return (oce_resume(dip));
 200  216          default:
 201  217                  return (DDI_FAILURE);
 202  218  
 203  219          case DDI_ATTACH:
 204  220                  break;
 205  221          }
 206  222  
 207  223          /* allocate dev */
 208  224          dev = kmem_zalloc(sizeof (struct oce_dev), KM_SLEEP);
 209  225  
 210  226          /* populate the dev structure */
 211  227          dev->dip = dip;
 212  228          dev->dev_id = ddi_get_instance(dip);
 213  229          dev->suspended = B_FALSE;
 214  230  
 215      -        dev->dev_list_index = MAX_DEVS;
 216      -        while (dev_index < MAX_DEVS) {
 217      -                (void) atomic_cas_ptr(&oce_dev_list[dev_index], NULL, dev);
 218      -                if (oce_dev_list[dev_index] == dev) {
 219      -                        break;
 220      -                }
 221      -                dev_index++;
 222      -        }
 223      -        if (dev_index == MAX_DEVS) {
 224      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 225      -                    "Too many oce devices on the system. Failed to attach.");
 226      -                goto attach_fail;
 227      -        }
 228      -        dev->dev_list_index = dev_index;
 229      -
 230  231          /* get the parameters */
 231  232          oce_get_params(dev);
 232  233  
 233  234          /*
 234  235           * set the ddi driver private data pointer. This is
 235  236           * sent to all mac callback entry points
 236  237           */
 237  238          ddi_set_driver_private(dip, dev);
 238  239  
 239  240          dev->attach_state |= ATTACH_DEV_INIT;
↓ open down ↓ 10 lines elided ↑ open up ↑
 250  251          dev->attach_state |= ATTACH_PCI_CFG;
 251  252  
 252  253          ret = oce_identify_hw(dev);
 253  254  
 254  255          if (ret != DDI_SUCCESS) {
 255  256                  oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 256  257                      "Device Unknown");
 257  258                  goto attach_fail;
 258  259          }
 259  260  
 260      -        ret = oce_get_bdf(dev);
 261      -        if (ret != DDI_SUCCESS) {
 262      -                oce_log(dev, CE_WARN, MOD_CONFIG,
 263      -                    "Failed to read BDF, status = 0x%x", ret);
 264      -                goto attach_fail;
 265      -        }
 266      -        /* Update the dev->rss */
 267      -        oce_dev_rss_ready(dev);
 268      -
 269  261          /* setup PCI bars */
 270  262          ret = oce_pci_init(dev);
 271  263          if (ret != DDI_SUCCESS) {
 272  264                  oce_log(dev, CE_WARN, MOD_CONFIG,
 273  265                      "PCI initialization failed with %d", ret);
 274  266                  goto attach_fail;
 275  267          }
 276  268          dev->attach_state |= ATTACH_PCI_INIT;
 277  269  
 278      -        ret = oce_setup_intr(dev);
 279      -        if (ret != DDI_SUCCESS) {
 280      -                oce_log(dev, CE_WARN, MOD_CONFIG,
 281      -                    "Interrupt setup failed with %d", ret);
 282      -                goto attach_fail;
 283      -
 284      -        }
 285      -        dev->attach_state |= ATTACH_SETUP_INTR;
 286      -
 287  270          /* initialize locks */
 288  271          oce_init_locks(dev);
 289  272          dev->attach_state |= ATTACH_LOCK_INIT;
 290  273  
 291      -
 292  274          /* HW init */
 293  275          ret = oce_hw_init(dev);
 294  276          if (ret != DDI_SUCCESS) {
 295  277                  oce_log(dev, CE_WARN, MOD_CONFIG,
 296  278                      "HW initialization failed with %d", ret);
 297  279                  goto attach_fail;
 298  280          }
 299  281          dev->attach_state |= ATTACH_HW_INIT;
 300  282  
 301      -        ret = oce_init_txrx(dev);
 302      -        if (ret  != DDI_SUCCESS) {
 303      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 304      -                    "Failed to init rings");
 305      -                goto attach_fail;
      283 +        /* Register IRM callback handler */
      284 +        if (oce_irm_enable != 0) {
      285 +                ret = ddi_cb_register(dev->dip, DDI_CB_FLAG_INTR, oce_cbfunc,
      286 +                    dev, NULL, &dev->cb_handle);
      287 +                if (ret != 0) {
      288 +                        oce_log(dev, CE_NOTE, MOD_CONFIG,
      289 +                            "Unable to register IRM callback: 0x%x", ret);
      290 +                        oce_irm_enable = 0;
      291 +                } else {
      292 +                        dev->attach_state |= ATTACH_CB_REG;
      293 +                        oce_irm_enable = 1;
      294 +                }
 306  295          }
 307      -        dev->attach_state |= ATTACH_SETUP_TXRX;
 308  296  
 309      -        ret = oce_setup_adapter(dev);
      297 +        /* Adjusting number of groups and rings */
      298 +        oce_group_rings(dev);
      299 +
      300 +        ret = oce_setup_intr(dev);
 310  301          if (ret != DDI_SUCCESS) {
      302 +                oce_log(dev, CE_WARN, MOD_CONFIG,
      303 +                    "Interrupt setup failed with %d", ret);
      304 +                goto attach_fail;
      305 +        }
      306 +        dev->attach_state |= ATTACH_SETUP_INTR;
      307 +
      308 +        if (oce_alloc_queues(dev) != DDI_SUCCESS) {
 311  309                  oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 312      -                    "Failed to setup adapter");
      310 +                    "Failed to allocate rings");
 313  311                  goto attach_fail;
 314  312          }
 315      -        dev->attach_state |=  ATTACH_SETUP_ADAP;
      313 +        dev->attach_state |= ATTACH_ALLOC_QUEUES;
 316  314  
 317      -
 318  315          ret = oce_stat_init(dev);
 319  316          if (ret != DDI_SUCCESS) {
 320  317                  oce_log(dev, CE_WARN, MOD_CONFIG,
 321  318                      "kstat setup Failed with %d", ret);
 322  319                  goto attach_fail;
 323  320          }
 324  321          dev->attach_state |= ATTACH_STAT_INIT;
 325  322  
      323 +        if (oce_setup_handlers(dev) != DDI_SUCCESS) {
      324 +                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
      325 +                    "Failed to Setup handlers");
      326 +                goto attach_fail;
      327 +        }
      328 +        dev->attach_state |= ATTACH_REG_INTR_HANDLE;
      329 +
 326  330          /* mac_register_t */
 327  331          oce_log(dev, CE_NOTE, MOD_CONFIG,
 328  332              "MAC_VERSION = 0x%x", MAC_VERSION);
 329  333          mac = mac_alloc(MAC_VERSION);
 330  334          if (mac == NULL) {
 331  335                  oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 332  336                      "MAC allocation Failed");
 333  337                  goto attach_fail;
 334  338          }
 335  339          /*
↓ open down ↓ 1 lines elided ↑ open up ↑
 337  341           */
 338  342          mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
 339  343          mac->m_driver = dev;
 340  344          mac->m_dip = dip;
 341  345          mac->m_src_addr = dev->mac_addr;
 342  346          mac->m_callbacks = &oce_mac_cb;
 343  347          mac->m_min_sdu = 0;
 344  348          mac->m_max_sdu = dev->mtu;
 345  349          mac->m_margin = VTAG_SIZE;
 346  350          mac->m_priv_props = oce_priv_props;
      351 +        mac->m_v12n = MAC_VIRT_LEVEL1;
 347  352  
 348  353          oce_log(dev, CE_NOTE, MOD_CONFIG,
 349  354              "Driver Private structure = 0x%p", (void *)dev);
 350  355  
 351  356          /* now register with GLDv3 */
 352  357          ret = mac_register(mac, (mac_handle_t *)&dev->mac_handle);
 353  358          /* regardless of the status, free mac_register */
 354  359          mac_free(mac);
 355  360          mac = NULL;
 356  361          if (ret != DDI_SUCCESS) {
 357  362                  oce_log(dev, CE_WARN, MOD_CONFIG,
 358  363                      "MAC registration failed :0x%x", ret);
 359  364                  goto attach_fail;
 360      -
 361  365          }
 362  366  
 363  367          /* correct link status only after start */
 364  368          dev->link_status = LINK_STATE_UNKNOWN;
 365  369          mac_link_update(dev->mac_handle, dev->link_status);
 366  370  
 367  371          dev->attach_state |= ATTACH_MAC_REG;
 368      -        dev->state |= STATE_INIT;
 369  372  
 370  373          oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
 371  374              "ATTACH SUCCESS");
 372  375  
 373  376          return (DDI_SUCCESS);
 374  377  
 375  378  attach_fail:
 376  379          oce_unconfigure(dev);
 377  380          return (DDI_FAILURE);
 378  381  } /* oce_attach */
 379  382  
 380  383  static int
 381  384  oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 382  385  {
 383  386          struct oce_dev *dev;
 384      -        int pcnt = 0;
 385      -        int qid;
      387 +        int ret = DDI_SUCCESS;
 386  388  
 387  389          dev = ddi_get_driver_private(dip);
 388  390          if (dev == NULL) {
 389  391                  return (DDI_FAILURE);
 390  392          }
 391      -        oce_log(dev, CE_NOTE, MOD_CONFIG,
 392      -            "Detaching driver: cmd = 0x%x", cmd);
 393  393  
 394  394          switch (cmd) {
 395  395          default:
 396  396                  return (DDI_FAILURE);
 397  397          case DDI_SUSPEND:
 398  398                  return (oce_suspend(dip));
 399  399          case DDI_DETACH:
 400  400                  break;
 401  401          } /* switch cmd */
 402  402  
 403      -        /* Fail detach if MAC unregister is unsuccessfule */
 404      -        if (mac_unregister(dev->mac_handle) != 0) {
 405      -                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
 406      -                    "Failed to unregister MAC ");
 407      -        }
 408      -        dev->attach_state &= ~ATTACH_MAC_REG;
 409      -
 410  403          /* check if the detach is called with out stopping */
 411  404          DEV_LOCK(dev);
 412  405          if (dev->state & STATE_MAC_STARTED) {
 413  406                  dev->state &= ~STATE_MAC_STARTED;
 414  407                  oce_stop(dev);
 415  408                  DEV_UNLOCK(dev);
 416  409          } else
 417  410                  DEV_UNLOCK(dev);
 418  411  
 419      -        /*
 420      -         * Wait for Packets sent up to be freed
 421      -         */
 422      -        for (qid = 0; qid < dev->rx_rings; qid++) {
 423      -                pcnt = oce_rx_pending(dev, dev->rq[qid], DEFAULT_DRAIN_TIME);
 424      -                if (pcnt != 0) {
 425      -                        oce_log(dev, CE_WARN, MOD_CONFIG,
 426      -                            "%d Pending Buffers Detach failed", pcnt);
 427      -                        return (DDI_FAILURE);
 428      -                }
 429      -        }
 430  412          oce_unconfigure(dev);
 431      -
 432      -        return (DDI_SUCCESS);
      413 +        return (ret);
 433  414  } /* oce_detach */
 434  415  
 435  416  static int
 436  417  oce_quiesce(dev_info_t *dip)
 437  418  {
 438  419          int ret = DDI_SUCCESS;
 439  420          struct oce_dev *dev = ddi_get_driver_private(dip);
 440  421  
 441  422          if (dev == NULL) {
 442  423                  return (DDI_FAILURE);
 443  424          }
 444  425          if (dev->suspended) {
 445  426                  return (DDI_SUCCESS);
 446  427          }
 447  428  
 448      -        oce_chip_di(dev);
      429 +        if (!LANCER_CHIP(dev)) {
      430 +                oce_chip_di(dev);
 449  431  
 450      -        ret = oce_reset_fun(dev);
      432 +                ret = oce_reset_fun(dev);
      433 +        } else {
      434 +                LANCER_IP_RESET;
      435 +        }
 451  436  
 452  437          return (ret);
 453  438  }
 454  439  
 455  440  static int
 456  441  oce_suspend(dev_info_t *dip)
 457  442  {
 458  443          struct oce_dev *dev = ddi_get_driver_private(dip);
      444 +        int i;
 459  445  
 460  446          mutex_enter(&dev->dev_lock);
 461  447          /* Suspend the card */
      448 +        if (dev->suspended || (!(dev->state & STATE_MAC_STARTED))) {
      449 +                mutex_exit(&dev->dev_lock);
      450 +                return (DDI_SUCCESS);
      451 +        }
 462  452          dev->suspended = B_TRUE;
 463      -        /* stop the adapter */
 464      -        if (dev->state & STATE_MAC_STARTED) {
 465      -                oce_stop(dev);
 466      -                oce_unsetup_adapter(dev);
      453 +
      454 +        /* stop the groups */
      455 +        for (i = 0; i < dev->num_rx_groups; i++) {
      456 +                mutex_enter(&dev->rx_group[i].grp_lock);
      457 +                oce_suspend_group_rings(&dev->rx_group[i]);
      458 +                oce_stop_group(&dev->rx_group[i], B_FALSE);
      459 +                mutex_exit(&dev->rx_group[i].grp_lock);
 467  460          }
 468      -        dev->state &= ~STATE_MAC_STARTED;
      461 +
      462 +        /* stop the adapter */
      463 +        oce_stop(dev);
      464 +
 469  465          mutex_exit(&dev->dev_lock);
      466 +        oce_disable_wd_timer(dev);
 470  467          return (DDI_SUCCESS);
 471  468  } /* oce_suspend */
 472  469  
 473  470  static int
 474  471  oce_resume(dev_info_t *dip)
 475  472  {
 476  473          struct oce_dev *dev;
 477      -        int ret;
      474 +        int i, ret = DDI_SUCCESS;
 478  475  
 479  476          /* get the dev pointer from dip */
 480  477          dev = ddi_get_driver_private(dip);
      478 +        if (dev == NULL) {
      479 +                return (DDI_FAILURE);
      480 +        }
 481  481          mutex_enter(&dev->dev_lock);
 482  482          if (!dev->suspended) {
 483  483                  mutex_exit(&dev->dev_lock);
 484  484                  return (DDI_SUCCESS);
 485  485          }
 486      -        if (!(dev->state & STATE_MAC_STARTED)) {
 487      -                ret = oce_setup_adapter(dev);
 488      -                if (ret != DDI_SUCCESS) {
 489      -                        mutex_exit(&dev->dev_lock);
 490      -                        return (DDI_FAILURE);
      486 +        if (dev->state & STATE_MAC_STARTED) {
      487 +                if ((ret = oce_start(dev)) != DDI_SUCCESS) {
      488 +                        goto resume_finish;
 491  489                  }
 492      -                ret = oce_start(dev);
 493      -                if (ret != DDI_SUCCESS) {
 494      -                        mutex_exit(&dev->dev_lock);
 495      -                        return (DDI_FAILURE);
      490 +
      491 +                /* re-start the groups */
      492 +                for (i = 0; i < dev->num_rx_groups; i++) {
      493 +                        mutex_enter(&dev->rx_group[i].grp_lock);
      494 +                        ret = oce_start_group(&dev->rx_group[i], B_FALSE);
      495 +                        if (ret == DDI_SUCCESS) {
      496 +                                ret = oce_resume_group_rings(&dev->rx_group[i]);
      497 +                        }
      498 +                        mutex_exit(&dev->rx_group[i].grp_lock);
      499 +                        if (ret != DDI_SUCCESS)
      500 +                                goto resume_finish;
 496  501                  }
      502 +                oce_enable_wd_timer(dev);
 497  503          }
 498  504          dev->suspended = B_FALSE;
 499      -        dev->state |= STATE_MAC_STARTED;
      505 +
      506 +resume_finish:
 500  507          mutex_exit(&dev->dev_lock);
 501  508          return (ret);
 502  509  } /* oce_resume */
 503  510  
 504  511  static void
 505  512  oce_init_locks(struct oce_dev *dev)
 506  513  {
 507  514          /* initialize locks */
 508  515          mutex_init(&dev->dev_lock, NULL, MUTEX_DRIVER,
 509  516              DDI_INTR_PRI(dev->intr_pri));
 510  517          mutex_init(&dev->bmbx_lock, NULL, MUTEX_DRIVER,
 511  518              DDI_INTR_PRI(dev->intr_pri));
      519 +        mutex_init(&dev->wd_lock, NULL, MUTEX_DRIVER,
      520 +            DDI_INTR_PRI(dev->intr_pri));
      521 +        mutex_init(&dev->stat_lock, NULL, MUTEX_DRIVER,
      522 +            DDI_INTR_PRI(dev->intr_pri));
 512  523  } /* oce_init_locks */
 513  524  
 514  525  static void
 515  526  oce_destroy_locks(struct oce_dev *dev)
 516  527  {
 517  528          mutex_destroy(&dev->dev_lock);
 518  529          mutex_destroy(&dev->bmbx_lock);
      530 +        mutex_destroy(&dev->wd_lock);
      531 +        mutex_destroy(&dev->stat_lock);
 519  532  } /* oce_destroy_locks */
 520  533  
 521  534  static void
 522  535  oce_unconfigure(struct oce_dev *dev)
 523  536  {
 524  537          uint32_t state = dev->attach_state;
 525  538  
 526  539          if (state & ATTACH_MAC_REG) {
 527  540                  (void) mac_unregister(dev->mac_handle);
 528  541          }
      542 +        if (state & ATTACH_REG_INTR_HANDLE) {
      543 +                oce_remove_handler(dev);
      544 +        }
 529  545          if (state & ATTACH_STAT_INIT) {
 530  546                  oce_stat_fini(dev);
 531  547          }
 532      -        if (state & ATTACH_SETUP_ADAP) {
 533      -                oce_unsetup_adapter(dev);
      548 +        if (state & ATTACH_CB_REG) {
      549 +                (void) ddi_cb_unregister(dev->cb_handle);
 534  550          }
 535      -        if (state & ATTACH_SETUP_TXRX) {
 536      -                oce_fini_txrx(dev);
      551 +        if (state & ATTACH_SETUP_INTR) {
      552 +                (void) oce_teardown_intr(dev);
 537  553          }
      554 +        if (state & ATTACH_ALLOC_QUEUES) {
      555 +                oce_free_queues(dev);
      556 +        }
 538  557          if (state & ATTACH_HW_INIT) {
 539  558                  oce_hw_fini(dev);
 540  559          }
 541  560          if (state & ATTACH_LOCK_INIT) {
 542  561                  oce_destroy_locks(dev);
 543  562          }
 544      -        if (state & ATTACH_SETUP_INTR) {
 545      -                (void) oce_teardown_intr(dev);
 546      -        }
 547  563          if (state & ATTACH_PCI_INIT) {
 548  564                  oce_pci_fini(dev);
 549  565          }
 550  566          if (state & ATTACH_PCI_CFG) {
 551  567                  pci_config_teardown(&dev->pci_cfg_handle);
 552  568          }
 553  569          if (state & ATTACH_FM_INIT) {
 554  570                  oce_fm_fini(dev);
 555  571          }
 556  572          if (state & ATTACH_DEV_INIT) {
 557  573                  ddi_set_driver_private(dev->dip, NULL);
 558      -                oce_dev_list[dev->dev_list_index] = NULL;
 559  574                  kmem_free(dev, sizeof (struct oce_dev));
 560  575          }
 561  576  } /* oce_unconfigure */
 562  577  
 563  578  static void
 564  579  oce_get_params(struct oce_dev *dev)
 565  580  {
 566  581          uint32_t log_level;
 567  582          uint16_t mod_mask;
 568  583          uint16_t severity;
↓ open down ↓ 8 lines elided ↑ open up ↑
 577  592          uint32_t tx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
 578  593              SIZE_2K, END};
 579  594          uint32_t rx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
 580  595              SIZE_2K, END};
 581  596          uint32_t rq_fs_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
 582  597          uint32_t rq_mb_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
 583  598          uint32_t lso_capable_values[] = {0, 1, END};
 584  599          uint32_t fm_caps_values[] = {DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY,
 585  600              END};
 586  601          uint32_t tx_rt_values[] = {END};
      602 +        uint32_t tx_reclaim_values[] = {END};
 587  603          uint32_t rx_ppi_values[] = {END};
 588  604          uint32_t rx_rings_values[] = {END};
      605 +        uint32_t rx_group_values[] = {END};
 589  606          uint32_t tx_rings_values[] = {END};
 590  607          uint32_t log_level_values[] = {END};
 591  608  
 592  609          /* non tunables  */
 593  610          dev->rx_ring_size = OCE_DEFAULT_RX_RING_SIZE;
 594  611  
 595  612          /* configurable parameters */
 596  613          dev->flow_control = oce_get_prop(dev, (char *)flow_control, OCE_FC_NONE,
 597  614              OCE_DEFAULT_FLOW_CONTROL, OCE_DEFAULT_FLOW_CONTROL, fc_values);
 598  615  
↓ open down ↓ 19 lines elided ↑ open up ↑
 618  635              1, 1, lso_capable_values);
 619  636  
 620  637          dev->fm_caps = oce_get_prop(dev, (char *)fm_cap_name,
 621  638              DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, OCE_FM_CAPABILITY,
 622  639              fm_caps_values);
 623  640  
 624  641          dev->tx_reclaim_threshold = oce_get_prop(dev,
 625  642              (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2,
 626  643              OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values);
 627  644  
      645 +        dev->tx_reclaim = oce_get_prop(dev, (char *)tx_reclaim, 1,
      646 +            dev->tx_reclaim_threshold, dev->tx_reclaim_threshold,
      647 +            tx_reclaim_values);
      648 +
 628  649          dev->rx_pkt_per_intr = oce_get_prop(dev, (char *)rx_pkt_per_intr_name,
 629      -            0, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKT_PER_INTR, rx_ppi_values);
      650 +            1, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKTS_PER_INTR,
      651 +            rx_ppi_values);
 630  652  
 631  653          dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name,
 632  654              OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values);
 633  655  
      656 +        dev->rx_rings_per_group = oce_get_prop(dev, (char *)rx_group_name,
      657 +            OCE_MIN_RING_PER_GROUP, OCE_MAX_RING_PER_GROUP,
      658 +            OCE_DEF_RING_PER_GROUP, rx_group_values);
      659 +
 634  660          dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name,
 635      -            OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values);
      661 +            OCE_MIN_WQ, OCE_MAX_WQ, OCE_DEFAULT_WQS, tx_rings_values);
 636  662  
 637  663          log_level = oce_get_prop(dev, (char *)log_level_name, 0,
 638  664              OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values);
 639  665  
 640  666          severity = (uint16_t)(log_level & 0xffff);
 641  667          mod_mask = (uint16_t)(log_level >> 16);
 642  668          if (mod_mask > MOD_ISR) {
 643  669                  mod_mask = 0;
 644  670          }
 645  671          if (severity > CE_IGNORE) {
↓ open down ↓ 25 lines elided ↑ open up ↑
 671  697                          break;
 672  698                  }
 673  699                  i++;
 674  700          }
 675  701  
 676  702          if ((i != 0) && (values[i] == 0xdeadface)) {
 677  703                  value = defval;
 678  704          }
 679  705  
 680  706          return (value);
      707 +}
      708 +
      709 +
      710 +static void oce_reset_wd_timer(struct oce_dev *dev)
      711 +{
      712 +        mutex_enter(&dev->wd_lock);
      713 +        if (dev->wd_enable) {
      714 +                oce_set_wd_timer(dev);
      715 +        }
      716 +        mutex_exit(&dev->wd_lock);
      717 +}
      718 +
      719 +static void oce_wd_timer(void *arg)
      720 +{
      721 +        struct oce_dev *dev = (struct oce_dev *)arg;
      722 +
      723 +        if (!LANCER_CHIP(dev)) {
      724 +                if (oce_check_ue(dev)) {
      725 +                        /* disable the watchdog and clean-up the interrupts */
      726 +                        oce_disable_wd_timer(dev);
      727 +                        mutex_enter(&dev->dev_lock);
      728 +                        (void) oce_di(dev);
      729 +                        ddi_fm_service_impact(dev->dip, DDI_SERVICE_LOST);
      730 +                        mutex_exit(&dev->dev_lock);
      731 +                        return;
      732 +                }
      733 +        }
      734 +
      735 +        if (oce_tx_stall_check(dev)) {
      736 +                oce_log(dev, CE_NOTE, MOD_CONFIG, "Tx Stall Detected at %lu",
      737 +                    ddi_get_lbolt());
      738 +        }
      739 +        /* restart the watch dog timer */
      740 +        oce_reset_wd_timer(dev);
      741 +}
      742 +
      743 +static void
      744 +oce_set_wd_timer(struct oce_dev *dev)
      745 +{
      746 +        dev->wd_id =
      747 +            timeout(oce_wd_timer, (void *) dev, drv_usectohz(1000000));
      748 +}
      749 +
      750 +void
      751 +oce_enable_wd_timer(struct oce_dev *dev)
      752 +{
      753 +
      754 +        mutex_enter(&dev->wd_lock);
      755 +        if (!dev->wd_enable) {
      756 +                dev->wd_enable = B_TRUE;
      757 +                oce_set_wd_timer(dev);
      758 +        }
      759 +        mutex_exit(&dev->wd_lock);
      760 +}
      761 +
      762 +void
      763 +oce_disable_wd_timer(struct oce_dev *dev)
      764 +{
      765 +        timeout_id_t wd_id;
      766 +        mutex_enter(&dev->wd_lock);
      767 +        dev->wd_enable = B_FALSE;
      768 +        wd_id = dev->wd_id;
      769 +        mutex_exit(&dev->wd_lock);
      770 +        if (wd_id != 0) {
      771 +                (void) untimeout(wd_id);
      772 +                dev->wd_id = 0;
      773 +        }
 681  774  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX