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

*** 17,56 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* Copyright © 2003-2011 Emulex. All rights reserved. */ /* * Source file containing the implementation of the driver entry points * and related helper functions */ #include <oce_impl.h> #include <oce_stat.h> #include <oce_ioctl.h> - #define ATTACH_DEV_INIT 0x1 - #define ATTACH_FM_INIT 0x2 - #define ATTACH_PCI_CFG 0x4 - #define ATTACH_LOCK_INIT 0x8 - #define ATTACH_PCI_INIT 0x10 - #define ATTACH_HW_INIT 0x20 - #define ATTACH_SETUP_TXRX 0x40 - #define ATTACH_SETUP_ADAP 0x80 - #define ATTACH_SETUP_INTR 0x100 - #define ATTACH_STAT_INIT 0x200 - #define ATTACH_MAC_REG 0x400 - /* ---[ globals and externs ]-------------------------------------------- */ const char oce_ident_string[] = OCE_IDENT_STRING; const char oce_mod_name[] = OCE_MOD_NAME; - struct oce_dev *oce_dev_list[MAX_DEVS + 1]; /* Last entry is invalid */ /* driver properties */ static const char flow_control[] = "flow_control"; static const char mtu_prop_name[] = "oce_default_mtu"; static const char tx_ring_size_name[] = "tx_ring_size"; static const char tx_bcopy_limit_name[] = "tx_bcopy_limit"; static const char rx_bcopy_limit_name[] = "rx_bcopy_limit"; --- 17,48 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* ! * Copyright (c) 2009-2012 Emulex. All rights reserved. ! * Use is subject to license terms. ! */ + /* * Source file containing the implementation of the driver entry points * and related helper functions */ #include <oce_impl.h> #include <oce_stat.h> #include <oce_ioctl.h> /* ---[ globals and externs ]-------------------------------------------- */ const char oce_ident_string[] = OCE_IDENT_STRING; const char oce_mod_name[] = OCE_MOD_NAME; /* driver properties */ + static const char tx_reclaim[] = "tx_reclaim"; static const char flow_control[] = "flow_control"; static const char mtu_prop_name[] = "oce_default_mtu"; static const char tx_ring_size_name[] = "tx_ring_size"; static const char tx_bcopy_limit_name[] = "tx_bcopy_limit"; static const char rx_bcopy_limit_name[] = "rx_bcopy_limit";
*** 60,69 **** --- 52,62 ---- static const char log_level_name[] = "oce_log_level"; static const char lso_capable_name[] = "lso_capable"; static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr"; static const char tx_reclaim_threshold_name[] = "tx_reclaim_threshold"; static const char rx_rings_name[] = "max_rx_rings"; + static const char rx_group_name[] = "max_rx_rings_per_group"; static const char tx_rings_name[] = "max_tx_rings"; /* --[ static function prototypes here ]------------------------------- */ static int oce_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd); static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
*** 74,83 **** --- 67,81 ---- static void oce_init_locks(struct oce_dev *dev); static void oce_destroy_locks(struct oce_dev *dev); static void oce_get_params(struct oce_dev *dev); static int oce_get_prop(struct oce_dev *dev, char *propname, int minval, int maxval, int defval, uint32_t *values); + static void oce_reset_wd_timer(struct oce_dev *dev); + static void oce_wd_timer(void *arg); + static void oce_set_wd_timer(struct oce_dev *dev); + int oce_alloc_queues(struct oce_dev *dev); + void oce_free_queues(struct oce_dev *dev); static struct cb_ops oce_cb_ops = { nulldev, /* cb_open */ nulldev, /* cb_close */ nodev, /* cb_strategy */
*** 121,141 **** static struct modlinkage oce_mod_linkage = { MODREV_1, &oce_drv, NULL }; ! #define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | \ ! MC_PROPINFO) static mac_callbacks_t oce_mac_cb = { OCE_M_CB_FLAGS, /* mc_callbacks */ oce_m_stat, /* mc_getstat */ oce_m_start, /* mc_start */ oce_m_stop, /* mc_stop */ oce_m_promiscuous, /* mc_setpromisc */ oce_m_multicast, /* mc_multicast */ ! oce_m_unicast, /* mc_unicast */ ! oce_m_send, /* mc_tx */ NULL, /* mc_reserve */ oce_m_ioctl, /* mc_ioctl */ oce_m_getcap, /* mc_getcapab */ NULL, /* open */ NULL, /* close */ --- 119,138 ---- static struct modlinkage oce_mod_linkage = { MODREV_1, &oce_drv, NULL }; ! #define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_PROPERTIES) static mac_callbacks_t oce_mac_cb = { OCE_M_CB_FLAGS, /* mc_callbacks */ oce_m_stat, /* mc_getstat */ oce_m_start, /* mc_start */ oce_m_stop, /* mc_stop */ oce_m_promiscuous, /* mc_setpromisc */ oce_m_multicast, /* mc_multicast */ ! NULL, /* mc_unicast */ ! NULL, /* mc_tx */ NULL, /* mc_reserve */ oce_m_ioctl, /* mc_ioctl */ oce_m_getcap, /* mc_getcapab */ NULL, /* open */ NULL, /* close */
*** 142,153 **** oce_m_setprop, /* set properties */ oce_m_getprop, /* get properties */ oce_m_propinfo /* properties info */ }; - extern char *oce_priv_props[]; /* Module Init */ int _info(struct modinfo *modinfop) { return (mod_info(&oce_mod_linkage, modinfop)); --- 139,169 ---- oce_m_setprop, /* set properties */ oce_m_getprop, /* get properties */ oce_m_propinfo /* properties info */ }; + /* array of properties supported by this driver */ + char *oce_priv_props[] = { + "_tx_rings", + "_tx_ring_size", + "_tx_bcopy_limit", + "_tx_reclaim_threshold", + "_rx_rings", + "_rx_rings_per_group", + "_rx_ring_size", + "_rx_bcopy_limit", + "_rx_pkts_per_intr", + "_log_level", + NULL + }; + + int oce_irm_enable = -1; + + extern int oce_cbfunc(dev_info_t *dip, ddi_cb_action_t cbaction, void *cbarg, + void *arg1, void *arg2); + /* Module Init */ int _info(struct modinfo *modinfop) { return (mod_info(&oce_mod_linkage, modinfop));
*** 157,167 **** _init(void) { int ret = 0; /* install the module */ ! mac_init_ops(&oce_dev_ops, "oce"); ret = mod_install(&oce_mod_linkage); if (ret) { cmn_err(CE_WARN, "mod_install failed rval=%x", ret); } --- 173,183 ---- _init(void) { int ret = 0; /* install the module */ ! mac_init_ops(&oce_dev_ops, OCE_MOD_NAME); ret = mod_install(&oce_mod_linkage); if (ret) { cmn_err(CE_WARN, "mod_install failed rval=%x", ret); }
*** 172,181 **** --- 188,198 ---- int _fini(void) { int ret = 0; + /* remove the module */ ret = mod_remove(&oce_mod_linkage); if (ret != 0) { return (ret); }
*** 190,200 **** oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int ret = 0; struct oce_dev *dev = NULL; mac_register_t *mac; - uint8_t dev_index = 0; switch (cmd) { case DDI_RESUME: return (oce_resume(dip)); default: --- 207,216 ----
*** 210,234 **** /* populate the dev structure */ dev->dip = dip; dev->dev_id = ddi_get_instance(dip); dev->suspended = B_FALSE; - dev->dev_list_index = MAX_DEVS; - while (dev_index < MAX_DEVS) { - (void) atomic_cas_ptr(&oce_dev_list[dev_index], NULL, dev); - if (oce_dev_list[dev_index] == dev) { - break; - } - dev_index++; - } - if (dev_index == MAX_DEVS) { - oce_log(dev, CE_WARN, MOD_CONFIG, "%s", - "Too many oce devices on the system. Failed to attach."); - goto attach_fail; - } - dev->dev_list_index = dev_index; - /* get the parameters */ oce_get_params(dev); /* * set the ddi driver private data pointer. This is --- 226,235 ----
*** 255,330 **** oce_log(dev, CE_WARN, MOD_CONFIG, "%s", "Device Unknown"); goto attach_fail; } - ret = oce_get_bdf(dev); - if (ret != DDI_SUCCESS) { - oce_log(dev, CE_WARN, MOD_CONFIG, - "Failed to read BDF, status = 0x%x", ret); - goto attach_fail; - } - /* Update the dev->rss */ - oce_dev_rss_ready(dev); - /* setup PCI bars */ ret = oce_pci_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "PCI initialization failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_PCI_INIT; - ret = oce_setup_intr(dev); - if (ret != DDI_SUCCESS) { - oce_log(dev, CE_WARN, MOD_CONFIG, - "Interrupt setup failed with %d", ret); - goto attach_fail; - - } - dev->attach_state |= ATTACH_SETUP_INTR; - /* initialize locks */ oce_init_locks(dev); dev->attach_state |= ATTACH_LOCK_INIT; - /* HW init */ ret = oce_hw_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "HW initialization failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_HW_INIT; ! ret = oce_init_txrx(dev); if (ret != DDI_SUCCESS) { ! oce_log(dev, CE_WARN, MOD_CONFIG, "%s", ! "Failed to init rings"); goto attach_fail; } ! dev->attach_state |= ATTACH_SETUP_TXRX; ! ret = oce_setup_adapter(dev); ! if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "%s", ! "Failed to setup adapter"); goto attach_fail; } ! dev->attach_state |= ATTACH_SETUP_ADAP; - ret = oce_stat_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "kstat setup Failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_STAT_INIT; /* mac_register_t */ oce_log(dev, CE_NOTE, MOD_CONFIG, "MAC_VERSION = 0x%x", MAC_VERSION); mac = mac_alloc(MAC_VERSION); if (mac == NULL) { --- 256,334 ---- oce_log(dev, CE_WARN, MOD_CONFIG, "%s", "Device Unknown"); goto attach_fail; } /* setup PCI bars */ ret = oce_pci_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "PCI initialization failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_PCI_INIT; /* initialize locks */ oce_init_locks(dev); dev->attach_state |= ATTACH_LOCK_INIT; /* HW init */ ret = oce_hw_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "HW initialization failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_HW_INIT; ! /* Register IRM callback handler */ ! if (oce_irm_enable != 0) { ! ret = ddi_cb_register(dev->dip, DDI_CB_FLAG_INTR, oce_cbfunc, ! dev, NULL, &dev->cb_handle); ! if (ret != 0) { ! oce_log(dev, CE_NOTE, MOD_CONFIG, ! "Unable to register IRM callback: 0x%x", ret); ! oce_irm_enable = 0; ! } else { ! dev->attach_state |= ATTACH_CB_REG; ! oce_irm_enable = 1; ! } ! } ! ! /* Adjusting number of groups and rings */ ! oce_group_rings(dev); ! ! ret = oce_setup_intr(dev); if (ret != DDI_SUCCESS) { ! oce_log(dev, CE_WARN, MOD_CONFIG, ! "Interrupt setup failed with %d", ret); goto attach_fail; } ! dev->attach_state |= ATTACH_SETUP_INTR; ! if (oce_alloc_queues(dev) != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "%s", ! "Failed to allocate rings"); goto attach_fail; } ! dev->attach_state |= ATTACH_ALLOC_QUEUES; ret = oce_stat_init(dev); if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "kstat setup Failed with %d", ret); goto attach_fail; } dev->attach_state |= ATTACH_STAT_INIT; + if (oce_setup_handlers(dev) != DDI_SUCCESS) { + oce_log(dev, CE_WARN, MOD_CONFIG, "%s", + "Failed to Setup handlers"); + goto attach_fail; + } + dev->attach_state |= ATTACH_REG_INTR_HANDLE; + /* mac_register_t */ oce_log(dev, CE_NOTE, MOD_CONFIG, "MAC_VERSION = 0x%x", MAC_VERSION); mac = mac_alloc(MAC_VERSION); if (mac == NULL) {
*** 342,351 **** --- 346,356 ---- mac->m_callbacks = &oce_mac_cb; mac->m_min_sdu = 0; mac->m_max_sdu = dev->mtu; mac->m_margin = VTAG_SIZE; mac->m_priv_props = oce_priv_props; + mac->m_v12n = MAC_VIRT_LEVEL1; oce_log(dev, CE_NOTE, MOD_CONFIG, "Driver Private structure = 0x%p", (void *)dev); /* now register with GLDv3 */
*** 355,373 **** mac = NULL; if (ret != DDI_SUCCESS) { oce_log(dev, CE_WARN, MOD_CONFIG, "MAC registration failed :0x%x", ret); goto attach_fail; - } /* correct link status only after start */ dev->link_status = LINK_STATE_UNKNOWN; mac_link_update(dev->mac_handle, dev->link_status); dev->attach_state |= ATTACH_MAC_REG; - dev->state |= STATE_INIT; oce_log(dev, CE_NOTE, MOD_CONFIG, "%s", "ATTACH SUCCESS"); return (DDI_SUCCESS); --- 360,376 ----
*** 379,397 **** static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { struct oce_dev *dev; ! int pcnt = 0; ! int qid; dev = ddi_get_driver_private(dip); if (dev == NULL) { return (DDI_FAILURE); } - oce_log(dev, CE_NOTE, MOD_CONFIG, - "Detaching driver: cmd = 0x%x", cmd); switch (cmd) { default: return (DDI_FAILURE); case DDI_SUSPEND: --- 382,397 ---- static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { struct oce_dev *dev; ! int ret = DDI_SUCCESS; dev = ddi_get_driver_private(dip); if (dev == NULL) { return (DDI_FAILURE); } switch (cmd) { default: return (DDI_FAILURE); case DDI_SUSPEND:
*** 398,437 **** return (oce_suspend(dip)); case DDI_DETACH: break; } /* switch cmd */ - /* Fail detach if MAC unregister is unsuccessfule */ - if (mac_unregister(dev->mac_handle) != 0) { - oce_log(dev, CE_WARN, MOD_CONFIG, "%s", - "Failed to unregister MAC "); - } - dev->attach_state &= ~ATTACH_MAC_REG; - /* check if the detach is called with out stopping */ DEV_LOCK(dev); if (dev->state & STATE_MAC_STARTED) { dev->state &= ~STATE_MAC_STARTED; oce_stop(dev); DEV_UNLOCK(dev); } else DEV_UNLOCK(dev); - /* - * Wait for Packets sent up to be freed - */ - for (qid = 0; qid < dev->rx_rings; qid++) { - pcnt = oce_rx_pending(dev, dev->rq[qid], DEFAULT_DRAIN_TIME); - if (pcnt != 0) { - oce_log(dev, CE_WARN, MOD_CONFIG, - "%d Pending Buffers Detach failed", pcnt); - return (DDI_FAILURE); - } - } oce_unconfigure(dev); ! ! return (DDI_SUCCESS); } /* oce_detach */ static int oce_quiesce(dev_info_t *dip) { --- 398,418 ---- return (oce_suspend(dip)); case DDI_DETACH: break; } /* switch cmd */ /* check if the detach is called with out stopping */ DEV_LOCK(dev); if (dev->state & STATE_MAC_STARTED) { dev->state &= ~STATE_MAC_STARTED; oce_stop(dev); DEV_UNLOCK(dev); } else DEV_UNLOCK(dev); oce_unconfigure(dev); ! return (ret); } /* oce_detach */ static int oce_quiesce(dev_info_t *dip) {
*** 443,504 **** } if (dev->suspended) { return (DDI_SUCCESS); } oce_chip_di(dev); ret = oce_reset_fun(dev); return (ret); } static int oce_suspend(dev_info_t *dip) { struct oce_dev *dev = ddi_get_driver_private(dip); mutex_enter(&dev->dev_lock); /* Suspend the card */ dev->suspended = B_TRUE; /* stop the adapter */ - if (dev->state & STATE_MAC_STARTED) { oce_stop(dev); ! oce_unsetup_adapter(dev); ! } ! dev->state &= ~STATE_MAC_STARTED; mutex_exit(&dev->dev_lock); return (DDI_SUCCESS); } /* oce_suspend */ static int oce_resume(dev_info_t *dip) { struct oce_dev *dev; ! int ret; /* get the dev pointer from dip */ dev = ddi_get_driver_private(dip); mutex_enter(&dev->dev_lock); if (!dev->suspended) { mutex_exit(&dev->dev_lock); return (DDI_SUCCESS); } ! if (!(dev->state & STATE_MAC_STARTED)) { ! ret = oce_setup_adapter(dev); ! if (ret != DDI_SUCCESS) { ! mutex_exit(&dev->dev_lock); ! return (DDI_FAILURE); } ! ret = oce_start(dev); ! if (ret != DDI_SUCCESS) { ! mutex_exit(&dev->dev_lock); ! return (DDI_FAILURE); } } dev->suspended = B_FALSE; ! dev->state |= STATE_MAC_STARTED; mutex_exit(&dev->dev_lock); return (ret); } /* oce_resume */ static void --- 424,511 ---- } if (dev->suspended) { return (DDI_SUCCESS); } + if (!LANCER_CHIP(dev)) { oce_chip_di(dev); ret = oce_reset_fun(dev); + } else { + LANCER_IP_RESET; + } return (ret); } static int oce_suspend(dev_info_t *dip) { struct oce_dev *dev = ddi_get_driver_private(dip); + int i; mutex_enter(&dev->dev_lock); /* Suspend the card */ + if (dev->suspended || (!(dev->state & STATE_MAC_STARTED))) { + mutex_exit(&dev->dev_lock); + return (DDI_SUCCESS); + } dev->suspended = B_TRUE; + + /* stop the groups */ + for (i = 0; i < dev->num_rx_groups; i++) { + mutex_enter(&dev->rx_group[i].grp_lock); + oce_suspend_group_rings(&dev->rx_group[i]); + oce_stop_group(&dev->rx_group[i], B_FALSE); + mutex_exit(&dev->rx_group[i].grp_lock); + } + /* stop the adapter */ oce_stop(dev); ! mutex_exit(&dev->dev_lock); + oce_disable_wd_timer(dev); return (DDI_SUCCESS); } /* oce_suspend */ static int oce_resume(dev_info_t *dip) { struct oce_dev *dev; ! int i, ret = DDI_SUCCESS; /* get the dev pointer from dip */ dev = ddi_get_driver_private(dip); + if (dev == NULL) { + return (DDI_FAILURE); + } mutex_enter(&dev->dev_lock); if (!dev->suspended) { mutex_exit(&dev->dev_lock); return (DDI_SUCCESS); } ! if (dev->state & STATE_MAC_STARTED) { ! if ((ret = oce_start(dev)) != DDI_SUCCESS) { ! goto resume_finish; } ! ! /* re-start the groups */ ! for (i = 0; i < dev->num_rx_groups; i++) { ! mutex_enter(&dev->rx_group[i].grp_lock); ! ret = oce_start_group(&dev->rx_group[i], B_FALSE); ! if (ret == DDI_SUCCESS) { ! ret = oce_resume_group_rings(&dev->rx_group[i]); } + mutex_exit(&dev->rx_group[i].grp_lock); + if (ret != DDI_SUCCESS) + goto resume_finish; } + oce_enable_wd_timer(dev); + } dev->suspended = B_FALSE; ! ! resume_finish: mutex_exit(&dev->dev_lock); return (ret); } /* oce_resume */ static void
*** 507,523 **** --- 514,536 ---- /* initialize locks */ mutex_init(&dev->dev_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(dev->intr_pri)); mutex_init(&dev->bmbx_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(dev->intr_pri)); + mutex_init(&dev->wd_lock, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(dev->intr_pri)); + mutex_init(&dev->stat_lock, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(dev->intr_pri)); } /* oce_init_locks */ static void oce_destroy_locks(struct oce_dev *dev) { mutex_destroy(&dev->dev_lock); mutex_destroy(&dev->bmbx_lock); + mutex_destroy(&dev->wd_lock); + mutex_destroy(&dev->stat_lock); } /* oce_destroy_locks */ static void oce_unconfigure(struct oce_dev *dev) {
*** 524,551 **** uint32_t state = dev->attach_state; if (state & ATTACH_MAC_REG) { (void) mac_unregister(dev->mac_handle); } if (state & ATTACH_STAT_INIT) { oce_stat_fini(dev); } ! if (state & ATTACH_SETUP_ADAP) { ! oce_unsetup_adapter(dev); } ! if (state & ATTACH_SETUP_TXRX) { ! oce_fini_txrx(dev); } if (state & ATTACH_HW_INIT) { oce_hw_fini(dev); } if (state & ATTACH_LOCK_INIT) { oce_destroy_locks(dev); } - if (state & ATTACH_SETUP_INTR) { - (void) oce_teardown_intr(dev); - } if (state & ATTACH_PCI_INIT) { oce_pci_fini(dev); } if (state & ATTACH_PCI_CFG) { pci_config_teardown(&dev->pci_cfg_handle); --- 537,567 ---- uint32_t state = dev->attach_state; if (state & ATTACH_MAC_REG) { (void) mac_unregister(dev->mac_handle); } + if (state & ATTACH_REG_INTR_HANDLE) { + oce_remove_handler(dev); + } if (state & ATTACH_STAT_INIT) { oce_stat_fini(dev); } ! if (state & ATTACH_CB_REG) { ! (void) ddi_cb_unregister(dev->cb_handle); } ! if (state & ATTACH_SETUP_INTR) { ! (void) oce_teardown_intr(dev); } + if (state & ATTACH_ALLOC_QUEUES) { + oce_free_queues(dev); + } if (state & ATTACH_HW_INIT) { oce_hw_fini(dev); } if (state & ATTACH_LOCK_INIT) { oce_destroy_locks(dev); } if (state & ATTACH_PCI_INIT) { oce_pci_fini(dev); } if (state & ATTACH_PCI_CFG) { pci_config_teardown(&dev->pci_cfg_handle);
*** 553,563 **** if (state & ATTACH_FM_INIT) { oce_fm_fini(dev); } if (state & ATTACH_DEV_INIT) { ddi_set_driver_private(dev->dip, NULL); - oce_dev_list[dev->dev_list_index] = NULL; kmem_free(dev, sizeof (struct oce_dev)); } } /* oce_unconfigure */ static void --- 569,578 ----
*** 582,593 **** --- 597,610 ---- uint32_t rq_mb_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END}; uint32_t lso_capable_values[] = {0, 1, END}; uint32_t fm_caps_values[] = {DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, END}; uint32_t tx_rt_values[] = {END}; + uint32_t tx_reclaim_values[] = {END}; uint32_t rx_ppi_values[] = {END}; uint32_t rx_rings_values[] = {END}; + uint32_t rx_group_values[] = {END}; uint32_t tx_rings_values[] = {END}; uint32_t log_level_values[] = {END}; /* non tunables */ dev->rx_ring_size = OCE_DEFAULT_RX_RING_SIZE;
*** 623,640 **** dev->tx_reclaim_threshold = oce_get_prop(dev, (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2, OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values); dev->rx_pkt_per_intr = oce_get_prop(dev, (char *)rx_pkt_per_intr_name, ! 0, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKT_PER_INTR, rx_ppi_values); dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name, OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values); dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name, ! OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values); log_level = oce_get_prop(dev, (char *)log_level_name, 0, OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values); severity = (uint16_t)(log_level & 0xffff); --- 640,666 ---- dev->tx_reclaim_threshold = oce_get_prop(dev, (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2, OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values); + dev->tx_reclaim = oce_get_prop(dev, (char *)tx_reclaim, 1, + dev->tx_reclaim_threshold, dev->tx_reclaim_threshold, + tx_reclaim_values); + dev->rx_pkt_per_intr = oce_get_prop(dev, (char *)rx_pkt_per_intr_name, ! 1, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKTS_PER_INTR, ! rx_ppi_values); dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name, OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values); + dev->rx_rings_per_group = oce_get_prop(dev, (char *)rx_group_name, + OCE_MIN_RING_PER_GROUP, OCE_MAX_RING_PER_GROUP, + OCE_DEF_RING_PER_GROUP, rx_group_values); + dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name, ! OCE_MIN_WQ, OCE_MAX_WQ, OCE_DEFAULT_WQS, tx_rings_values); log_level = oce_get_prop(dev, (char *)log_level_name, 0, OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values); severity = (uint16_t)(log_level & 0xffff);
*** 676,681 **** --- 702,774 ---- if ((i != 0) && (values[i] == 0xdeadface)) { value = defval; } return (value); + } + + + static void oce_reset_wd_timer(struct oce_dev *dev) + { + mutex_enter(&dev->wd_lock); + if (dev->wd_enable) { + oce_set_wd_timer(dev); + } + mutex_exit(&dev->wd_lock); + } + + static void oce_wd_timer(void *arg) + { + struct oce_dev *dev = (struct oce_dev *)arg; + + if (!LANCER_CHIP(dev)) { + if (oce_check_ue(dev)) { + /* disable the watchdog and clean-up the interrupts */ + oce_disable_wd_timer(dev); + mutex_enter(&dev->dev_lock); + (void) oce_di(dev); + ddi_fm_service_impact(dev->dip, DDI_SERVICE_LOST); + mutex_exit(&dev->dev_lock); + return; + } + } + + if (oce_tx_stall_check(dev)) { + oce_log(dev, CE_NOTE, MOD_CONFIG, "Tx Stall Detected at %lu", + ddi_get_lbolt()); + } + /* restart the watch dog timer */ + oce_reset_wd_timer(dev); + } + + static void + oce_set_wd_timer(struct oce_dev *dev) + { + dev->wd_id = + timeout(oce_wd_timer, (void *) dev, drv_usectohz(1000000)); + } + + void + oce_enable_wd_timer(struct oce_dev *dev) + { + + mutex_enter(&dev->wd_lock); + if (!dev->wd_enable) { + dev->wd_enable = B_TRUE; + oce_set_wd_timer(dev); + } + mutex_exit(&dev->wd_lock); + } + + void + oce_disable_wd_timer(struct oce_dev *dev) + { + timeout_id_t wd_id; + mutex_enter(&dev->wd_lock); + dev->wd_enable = B_FALSE; + wd_id = dev->wd_id; + mutex_exit(&dev->wd_lock); + if (wd_id != 0) { + (void) untimeout(wd_id); + dev->wd_id = 0; + } }