diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index f362e51c73ee..5df971aca9e3 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -211,7 +211,7 @@ void wx_get_pause_stats(struct net_device *netdev, hwstats = &wx->stats; stats->tx_pause_frames = hwstats->lxontxc + hwstats->lxofftxc; - stats->rx_pause_frames = hwstats->lxonoffrxc; + stats->rx_pause_frames = hwstats->lxonrxc + hwstats->lxoffrxc; } EXPORT_SYMBOL(wx_get_pause_stats); @@ -262,6 +262,39 @@ int wx_set_link_ksettings(struct net_device *netdev, } EXPORT_SYMBOL(wx_set_link_ksettings); +void wx_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct wx *wx = netdev_priv(netdev); + + if (!wx->wol_hw_supported) + return; + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + if (wx->wol & WX_PSR_WKUP_CTL_MAG) + wol->wolopts |= WAKE_MAGIC; +} +EXPORT_SYMBOL(wx_get_wol); + +int wx_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct wx *wx = netdev_priv(netdev); + struct pci_dev *pdev = wx->pdev; + + if (!wx->wol_hw_supported) + return -EOPNOTSUPP; + + wx->wol = 0; + if (wol->wolopts & WAKE_MAGIC) + wx->wol = WX_PSR_WKUP_CTL_MAG; + wr32(wx, WX_PSR_WKUP_CTL, wx->wol); + device_set_wakeup_enable(&pdev->dev, !!(wx->wol)); + + return 0; +} +EXPORT_SYMBOL(wx_set_wol); + void wx_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { @@ -522,7 +555,7 @@ int wx_set_channels(struct net_device *dev, wx->ring_feature[RING_F_RSS].limit = count; - return 0; + return wx->setup_tc(dev, netdev_get_num_tc(dev)); } EXPORT_SYMBOL(wx_set_channels); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h index 727093970462..5b187d1587b1 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h @@ -18,6 +18,10 @@ int wx_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd); int wx_set_link_ksettings(struct net_device *netdev, const struct ethtool_link_ksettings *cmd); +void wx_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol); +int wx_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol); void wx_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause); int wx_set_pauseparam(struct net_device *netdev, diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index bee9e245e792..d3772d01e00b 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2513,6 +2513,8 @@ int wx_sw_init(struct wx *wx) return -ENOMEM; } + spin_lock_init(&wx->hw_stats_lock); + mutex_init(&wx->reset_lock); bitmap_zero(wx->state, WX_STATE_NBITS); bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS); wx->misc_irq_domain = false; @@ -2772,6 +2774,15 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause) } } + if (rx_pause && tx_pause) + wx->fc.mode = wx_fc_full; + else if (rx_pause) + wx->fc.mode = wx_fc_rx_pause; + else if (tx_pause) + wx->fc.mode = wx_fc_tx_pause; + else + wx->fc.mode = wx_fc_none; + /* Disable any previous flow control settings */ mflcn_reg = rd32(wx, WX_MAC_RX_FLOW_CTRL); mflcn_reg &= ~WX_MAC_RX_FLOW_CTRL_RFE; @@ -2790,7 +2801,9 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause) /* Set up and enable Rx high/low water mark thresholds, enable XON. */ if (tx_pause && wx->fc.high_water) { - fcrtl = (wx->fc.low_water << 10) | WX_RDB_RFCL_XONE; + fcrtl = (wx->fc.low_water << 10); + if (wx->mac.type != wx_mac_sp) + fcrtl |= WX_RDB_RFCL_XONE; wr32(wx, WX_RDB_RFCL, fcrtl); fcrth = (wx->fc.high_water << 10) | WX_RDB_RFCH_XOFFE; } else { @@ -2831,6 +2844,21 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause) } EXPORT_SYMBOL(wx_fc_enable); +static void wx_update_xoff_rx_lfc(struct wx *wx) +{ + struct wx_hw_stats *hwstats = &wx->stats; + + if (wx->fc.mode != wx_fc_full && + wx->fc.mode != wx_fc_rx_pause) + return; + + if (wx->mac.type >= wx_mac_aml) + hwstats->lxoffrxc += rd32_wrap(wx, WX_MAC_LXOFFRXC_AML, + &wx->last_stats.lxoffrxc); + else + hwstats->lxoffrxc += rd64(wx, WX_MAC_LXOFFRXC); +} + /** * wx_update_stats - Update the board statistics counters. * @wx: board private structure @@ -2844,6 +2872,12 @@ void wx_update_stats(struct wx *wx) u64 restart_queue = 0, tx_busy = 0; u32 i; + if (!netif_running(wx->netdev) || + test_bit(WX_STATE_RESETTING, wx->state)) + return; + + spin_lock(&wx->hw_stats_lock); + /* gather some stats to the wx struct that are per queue */ for (i = 0; i < wx->num_rx_queues; i++) { struct wx_ring *rx_ring = wx->rx_ring[i]; @@ -2879,6 +2913,8 @@ void wx_update_stats(struct wx *wx) wx->restart_queue = restart_queue; wx->tx_busy = tx_busy; + wx_update_xoff_rx_lfc(wx); + hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT); hwstats->gptc += rd32(wx, WX_TDM_PKT_CNT); hwstats->gorc += rd64(wx, WX_RDM_BYTE_CNT_LSB); @@ -2893,7 +2929,11 @@ void wx_update_stats(struct wx *wx) hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L); hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD); hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD); - hwstats->lxonoffrxc += rd32(wx, WX_MAC_LXONOFFRXC); + if (wx->mac.type >= wx_mac_aml) + hwstats->lxonrxc += rd32_wrap(wx, WX_MAC_LXONRXC_AML, + &wx->last_stats.lxonrxc); + else + hwstats->lxonrxc += rd32(wx, WX_MAC_LXONRXC); hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC); hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC); hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT); @@ -2907,11 +2947,12 @@ void wx_update_stats(struct wx *wx) hwstats->fdirmiss += rd32(wx, WX_RDB_FDIR_MISS); } - /* qmprc is not cleared on read, manual reset it */ - hwstats->qmprc = 0; for (i = wx->num_vfs * wx->num_rx_queues_per_pool; i < wx->mac.max_rx_queues; i++) - hwstats->qmprc += rd32(wx, WX_PX_MPRC(i)); + hwstats->qmprc += rd32_wrap(wx, WX_PX_MPRC(i), + &wx->last_stats.qmprc[i]); + + spin_unlock(&wx->hw_stats_lock); } EXPORT_SYMBOL(wx_update_stats); @@ -2926,8 +2967,11 @@ void wx_clear_hw_cntrs(struct wx *wx) { u16 i = 0; - for (i = 0; i < wx->mac.max_rx_queues; i++) + for (i = wx->num_vfs * wx->num_rx_queues_per_pool; + i < wx->mac.max_rx_queues; i++) { wr32(wx, WX_PX_MPRC(i), 0); + wx->last_stats.qmprc[i] = 0; + } rd32(wx, WX_RDM_PKT_CNT); rd32(wx, WX_TDM_PKT_CNT); @@ -2946,7 +2990,15 @@ void wx_clear_hw_cntrs(struct wx *wx) rd64(wx, WX_RX_LEN_ERROR_FRAMES_L); rd32(wx, WX_RDB_LXONTXC); rd32(wx, WX_RDB_LXOFFTXC); - rd32(wx, WX_MAC_LXONOFFRXC); + if (wx->mac.type >= wx_mac_aml) { + wr32(wx, WX_MAC_LXONRXC_AML, 0); + wr32(wx, WX_MAC_LXOFFRXC_AML, 0); + wx->last_stats.lxonrxc = 0; + wx->last_stats.lxoffrxc = 0; + } else { + rd32(wx, WX_MAC_LXONRXC); + rd64(wx, WX_MAC_LXOFFRXC); + } } EXPORT_SYMBOL(wx_clear_hw_cntrs); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index 29e5c5470c94..0da5565ee4ff 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -79,7 +79,10 @@ #define WX_RX_LEN_ERROR_FRAMES_L 0x11978 #define WX_RX_UNDERSIZE_FRAMES_GOOD 0x11938 #define WX_RX_OVERSIZE_FRAMES_GOOD 0x1193C -#define WX_MAC_LXONOFFRXC 0x11E0C +#define WX_MAC_LXOFFRXC 0x11988 +#define WX_MAC_LXONRXC 0x11E0C +#define WX_MAC_LXOFFRXC_AML 0x11F80 +#define WX_MAC_LXONRXC_AML 0x11F84 /*********************** Receive DMA registers **************************/ #define WX_RDM_VF_RE(_i) (0x12004 + ((_i) * 4)) @@ -1148,9 +1151,18 @@ enum wx_isb_idx { WX_ISB_MAX }; +/* Flow Control Settings */ +enum wx_fc_mode { + wx_fc_none = 0, + wx_fc_rx_pause, + wx_fc_tx_pause, + wx_fc_full +}; + struct wx_fc_info { u32 high_water; /* Flow Ctrl High-water */ u32 low_water; /* Flow Ctrl Low-water */ + enum wx_fc_mode mode; /* Flow Control Mode */ }; /* Statistics counters collected by the MAC */ @@ -1167,7 +1179,8 @@ struct wx_hw_stats { u64 mptc; u64 roc; u64 ruc; - u64 lxonoffrxc; + u64 lxonrxc; + u64 lxoffrxc; u64 lxontxc; u64 lxofftxc; u64 o2bgptc; @@ -1182,6 +1195,12 @@ struct wx_hw_stats { u64 fdirmiss; }; +struct wx_last_stats { + u32 qmprc[128]; + u32 lxoffrxc; + u32 lxonrxc; +}; + enum wx_state { WX_STATE_RESETTING, WX_STATE_SWFW_BUSY, @@ -1354,6 +1373,8 @@ struct wx { bool default_up; struct wx_hw_stats stats; + struct wx_last_stats last_stats; + spinlock_t hw_stats_lock; /* spinlock for accessing to hw stats */ u64 tx_busy; u64 non_eop_descs; u64 restart_queue; @@ -1400,6 +1421,7 @@ struct wx { struct timer_list service_timer; struct work_struct service_task; + struct mutex reset_lock; /* mutex for reset */ }; #define WX_INTR_ALL (~0ULL) @@ -1462,6 +1484,18 @@ wr32ptp(struct wx *wx, u32 reg, u32 value) return wr32(wx, reg + 0xB500, value); } +static inline u32 +rd32_wrap(struct wx *wx, u32 reg, u32 *last) +{ + u32 val, delta; + + val = rd32(wx, reg); + delta = val - *last; + *last = val; + + return delta; +} + /* On some domestic CPU platforms, sometimes IO is not synchronized with * flushing memory, here use readl() to flush PCI read and write. */ @@ -1478,21 +1512,6 @@ static inline struct wx *phylink_to_wx(struct phylink_config *config) return container_of(config, struct wx, phylink_config); } -static inline int wx_set_state_reset(struct wx *wx) -{ - u8 timeout = 50; - - while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) { - timeout--; - if (!timeout) - return -EBUSY; - - usleep_range(1000, 2000); - } - - return 0; -} - static inline unsigned int wx_rx_pg_order(struct wx_ring *ring) { #if (PAGE_SIZE < 8192) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c index ade2bfe563aa..29cdbed2e5ec 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_common.c @@ -48,9 +48,10 @@ void wxvf_remove(struct pci_dev *pdev) struct wx *wx = pci_get_drvdata(pdev); struct net_device *netdev; - cancel_work_sync(&wx->service_task); netdev = wx->netdev; unregister_netdev(netdev); + timer_shutdown_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); kfree(wx->vfinfo); kfree(wx->rss_key); kfree(wx->mac_table); @@ -339,14 +340,16 @@ static void wxvf_down(struct wx *wx) static void wxvf_reinit_locked(struct wx *wx) { - while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) - usleep_range(1000, 2000); + mutex_lock(&wx->reset_lock); + set_bit(WX_STATE_RESETTING, wx->state); + wxvf_down(wx); wx_free_irq(wx); wx_configure_vf(wx); wx_request_msix_irqs_vf(wx); wxvf_up_complete(wx); clear_bit(WX_STATE_RESETTING, wx->state); + mutex_unlock(&wx->reset_lock); } static void wxvf_reset_subtask(struct wx *wx) diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c index fc04040957bf..b2e191982803 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c @@ -12,38 +12,6 @@ #include "ngbe_ethtool.h" #include "ngbe_type.h" -static void ngbe_get_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct wx *wx = netdev_priv(netdev); - - if (!wx->wol_hw_supported) - return; - wol->supported = WAKE_MAGIC; - wol->wolopts = 0; - if (wx->wol & WX_PSR_WKUP_CTL_MAG) - wol->wolopts |= WAKE_MAGIC; -} - -static int ngbe_set_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct wx *wx = netdev_priv(netdev); - struct pci_dev *pdev = wx->pdev; - - if (!wx->wol_hw_supported) - return -EOPNOTSUPP; - - wx->wol = 0; - if (wol->wolopts & WAKE_MAGIC) - wx->wol = WX_PSR_WKUP_CTL_MAG; - netdev->ethtool->wol_enabled = !!(wx->wol); - wr32(wx, WX_PSR_WKUP_CTL, wx->wol); - device_set_wakeup_enable(&pdev->dev, netdev->ethtool->wol_enabled); - - return 0; -} - static int ngbe_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, struct kernel_ethtool_ringparam *kernel_ring, @@ -64,9 +32,8 @@ static int ngbe_set_ringparam(struct net_device *netdev, new_rx_count == wx->rx_ring_count) return 0; - err = wx_set_state_reset(wx); - if (err) - return err; + mutex_lock(&wx->reset_lock); + set_bit(WX_STATE_RESETTING, wx->state); if (!netif_running(wx->netdev)) { for (i = 0; i < wx->num_tx_queues; i++) @@ -97,22 +64,10 @@ static int ngbe_set_ringparam(struct net_device *netdev, clear_reset: clear_bit(WX_STATE_RESETTING, wx->state); + mutex_unlock(&wx->reset_lock); return err; } -static int ngbe_set_channels(struct net_device *dev, - struct ethtool_channels *ch) -{ - int err; - - err = wx_set_channels(dev, ch); - if (err < 0) - return err; - - /* use setup TC to update any traffic class queue mapping */ - return ngbe_setup_tc(dev, netdev_get_num_tc(dev)); -} - static const struct ethtool_ops ngbe_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | @@ -122,8 +77,8 @@ static const struct ethtool_ops ngbe_ethtool_ops = { .get_link_ksettings = wx_get_link_ksettings, .set_link_ksettings = wx_set_link_ksettings, .nway_reset = wx_nway_reset, - .get_wol = ngbe_get_wol, - .set_wol = ngbe_set_wol, + .get_wol = wx_get_wol, + .set_wol = wx_set_wol, .get_sset_count = wx_get_sset_count, .get_strings = wx_get_strings, .get_ethtool_stats = wx_get_ethtool_stats, @@ -136,7 +91,7 @@ static const struct ethtool_ops ngbe_ethtool_ops = { .get_coalesce = wx_get_coalesce, .set_coalesce = wx_set_coalesce, .get_channels = wx_get_channels, - .set_channels = ngbe_set_channels, + .set_channels = wx_set_channels, .get_rxfh_fields = wx_get_rxfh_fields, .set_rxfh_fields = wx_set_rxfh_fields, .get_rxfh_indir_size = wx_rss_indir_size, diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c index 58488e138beb..d8e3827a8b1f 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c @@ -57,16 +57,16 @@ static void ngbe_init_type_code(struct wx *wx) wx->mac.type = wx_mac_em; type_mask = (u16)(wx->subsystem_device_id & NGBE_OEM_MASK); - ncsi_mask = wx->subsystem_device_id & NGBE_NCSI_MASK; - wol_mask = wx->subsystem_device_id & NGBE_WOL_MASK; + ncsi_mask = wx->subsystem_device_id & WX_NCSI_MASK; + wol_mask = wx->subsystem_device_id & WX_WOL_MASK; val = rd32(wx, WX_CFG_PORT_ST); wx->mac_type = (val & BIT(7)) >> 7 ? em_mac_type_rgmii : em_mac_type_mdi; - wx->wol_hw_supported = (wol_mask == NGBE_WOL_SUP) ? 1 : 0; - wx->ncsi_enabled = (ncsi_mask == NGBE_NCSI_MASK || + wx->wol_hw_supported = (wol_mask == WX_WOL_SUP) ? 1 : 0; + wx->ncsi_enabled = (ncsi_mask == WX_NCSI_SUP || type_mask == NGBE_SUBID_OCP_CARD) ? 1 : 0; switch (type_mask) { @@ -138,6 +138,26 @@ static int ngbe_sw_init(struct wx *wx) return 0; } +/** + * ngbe_service_task - manages and runs subtasks + * @work: pointer to work_struct containing our data + **/ +static void ngbe_service_task(struct work_struct *work) +{ + struct wx *wx = container_of(work, struct wx, service_task); + + wx_update_stats(wx); + + wx_service_event_complete(wx); +} + +static void ngbe_init_service(struct wx *wx) +{ + timer_setup(&wx->service_timer, wx_service_timer, 0); + INIT_WORK(&wx->service_task, ngbe_service_task); + clear_bit(WX_STATE_SERVICE_SCHED, wx->state); +} + /** * ngbe_irq_enable - Enable default interrupt generation settings * @wx: board private structure @@ -368,6 +388,10 @@ static void ngbe_disable_device(struct wx *wx) wx_napi_disable_all(wx); netif_tx_stop_all_queues(netdev); netif_tx_disable(netdev); + + timer_delete_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); + if (wx->gpio_ctrl) ngbe_sfp_modules_txrx_powerctl(wx, false); wx_irq_disable(wx); @@ -407,6 +431,7 @@ void ngbe_up(struct wx *wx) wx_napi_enable_all(wx); /* enable transmits */ netif_tx_start_all_queues(wx->netdev); + mod_timer(&wx->service_timer, jiffies); /* clear any pending interrupts, may auto mask */ rd32(wx, WX_PX_IC(0)); @@ -520,9 +545,9 @@ static void ngbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake) if (wufc) { wx_set_rx_mode(netdev); wx_configure_rx(wx); - wr32(wx, NGBE_PSR_WKUP_CTL, wufc); + wr32(wx, WX_PSR_WKUP_CTL, wufc); } else { - wr32(wx, NGBE_PSR_WKUP_CTL, 0); + wr32(wx, WX_PSR_WKUP_CTL, 0); } pci_wake_from_d3(pdev, !!wufc); *enable_wake = !!wufc; @@ -742,10 +767,10 @@ static int ngbe_probe(struct pci_dev *pdev, wx->wol = 0; if (wx->wol_hw_supported) - wx->wol = NGBE_PSR_WKUP_CTL_MAG; + wx->wol = WX_PSR_WKUP_CTL_MAG; netdev->ethtool->wol_enabled = !!(wx->wol); - wr32(wx, NGBE_PSR_WKUP_CTL, wx->wol); + wr32(wx, WX_PSR_WKUP_CTL, wx->wol); device_set_wakeup_enable(&pdev->dev, wx->wol); /* Save off EEPROM version number and Option Rom version which @@ -770,9 +795,11 @@ static int ngbe_probe(struct pci_dev *pdev, eth_hw_addr_set(netdev, wx->mac.perm_addr); wx_mac_set_default_filter(wx, wx->mac.perm_addr); + ngbe_init_service(wx); + err = wx_init_interrupt_scheme(wx); if (err) - goto err_free_mac_table; + goto err_cancel_service; /* phy Interface Configuration */ err = ngbe_mdio_init(wx); @@ -792,6 +819,9 @@ static int ngbe_probe(struct pci_dev *pdev, wx_control_hw(wx, false); err_clear_interrupt_scheme: wx_clear_interrupt_scheme(wx); +err_cancel_service: + timer_delete_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); err_free_mac_table: kfree(wx->rss_key); kfree(wx->mac_table); @@ -820,6 +850,10 @@ static void ngbe_remove(struct pci_dev *pdev) netdev = wx->netdev; wx_disable_sriov(wx); unregister_netdev(netdev); + + timer_shutdown_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); + phylink_destroy(wx->phylink); pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h b/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h index 3b2ca7f47e33..7077a0da4c98 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h @@ -37,11 +37,6 @@ #define NGBE_OEM_MASK 0x00FF -#define NGBE_NCSI_SUP 0x8000 -#define NGBE_NCSI_MASK 0x8000 -#define NGBE_WOL_SUP 0x4000 -#define NGBE_WOL_MASK 0x4000 - /**************** EM Registers ****************************/ /* chip control Registers */ #define NGBE_MIS_PRB_CTL 0x10010 @@ -93,18 +88,6 @@ #define NGBE_CFG_LAN_SPEED 0x14440 #define NGBE_CFG_PORT_ST 0x14404 -/* Wake up registers */ -#define NGBE_PSR_WKUP_CTL 0x15B80 -/* Wake Up Filter Control Bit */ -#define NGBE_PSR_WKUP_CTL_LNKC BIT(0) /* Link Status Change Wakeup Enable*/ -#define NGBE_PSR_WKUP_CTL_MAG BIT(1) /* Magic Packet Wakeup Enable */ -#define NGBE_PSR_WKUP_CTL_EX BIT(2) /* Directed Exact Wakeup Enable */ -#define NGBE_PSR_WKUP_CTL_MC BIT(3) /* Directed Multicast Wakeup Enable*/ -#define NGBE_PSR_WKUP_CTL_BC BIT(4) /* Broadcast Wakeup Enable */ -#define NGBE_PSR_WKUP_CTL_ARP BIT(5) /* ARP Request Packet Wakeup Enable*/ -#define NGBE_PSR_WKUP_CTL_IPV4 BIT(6) /* Directed IPv4 Pkt Wakeup Enable */ -#define NGBE_PSR_WKUP_CTL_IPV6 BIT(7) /* Directed IPv6 Pkt Wakeup Enable */ - #define NGBE_FW_EEPROM_CHECKSUM_CMD 0xE9 #define NGBE_FW_NVM_DATA_OFFSET 3 #define NGBE_FW_CMD_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c index 9157b8275be1..3e32aca72806 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c @@ -56,9 +56,8 @@ static int txgbe_set_ringparam(struct net_device *netdev, new_rx_count == wx->rx_ring_count) return 0; - err = wx_set_state_reset(wx); - if (err) - return err; + mutex_lock(&wx->reset_lock); + set_bit(WX_STATE_RESETTING, wx->state); if (!netif_running(wx->netdev)) { for (i = 0; i < wx->num_tx_queues; i++) @@ -88,22 +87,10 @@ static int txgbe_set_ringparam(struct net_device *netdev, clear_reset: clear_bit(WX_STATE_RESETTING, wx->state); + mutex_unlock(&wx->reset_lock); return err; } -static int txgbe_set_channels(struct net_device *dev, - struct ethtool_channels *ch) -{ - int err; - - err = wx_set_channels(dev, ch); - if (err < 0) - return err; - - /* use setup TC to update any traffic class queue mapping */ - return txgbe_setup_tc(dev, netdev_get_num_tc(dev)); -} - static int txgbe_get_ethtool_fdir_entry(struct txgbe *txgbe, struct ethtool_rxnfc *cmd) { @@ -587,7 +574,7 @@ static const struct ethtool_ops txgbe_ethtool_ops = { .get_coalesce = wx_get_coalesce, .set_coalesce = wx_set_coalesce, .get_channels = wx_get_channels, - .set_channels = txgbe_set_channels, + .set_channels = wx_set_channels, .get_rxnfc = txgbe_get_rxnfc, .set_rxnfc = txgbe_set_rxnfc, .get_rx_ring_count = txgbe_get_rx_ring_count, diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index 0de051450a82..ec32a5f422f2 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -130,6 +130,7 @@ static void txgbe_service_task(struct work_struct *work) txgbe_module_detection_subtask(wx); txgbe_link_config_subtask(wx); + wx_update_stats(wx); wx_service_event_complete(wx); } @@ -598,20 +599,16 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc) static void txgbe_reinit_locked(struct wx *wx) { - int err = 0; - netif_trans_update(wx->netdev); - err = wx_set_state_reset(wx); - if (err) { - wx_err(wx, "wait device reset timeout\n"); - return; - } + mutex_lock(&wx->reset_lock); + set_bit(WX_STATE_RESETTING, wx->state); txgbe_down(wx); txgbe_up(wx); clear_bit(WX_STATE_RESETTING, wx->state); + mutex_unlock(&wx->reset_lock); } void txgbe_do_reset(struct net_device *netdev) @@ -950,12 +947,13 @@ static void txgbe_remove(struct pci_dev *pdev) struct txgbe *txgbe = wx->priv; struct net_device *netdev; - cancel_work_sync(&wx->service_task); - netdev = wx->netdev; wx_disable_sriov(wx); unregister_netdev(netdev); + timer_shutdown_sync(&wx->service_timer); + cancel_work_sync(&wx->service_task); + txgbe_remove_phy(txgbe); wx_free_isb_resources(wx);