Merge branch 'wangxun-improvement'

Jiawen Wu says:

====================
Wangxun improvement

This patch series cleans up the code and enhances the implementation.
====================

Link: https://patch.msgid.link/20260407025616.33652-1-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-04-12 08:42:30 -07:00
commit 17ad4759a0
10 changed files with 200 additions and 132 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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));

View File

@ -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 */

View File

@ -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,

View File

@ -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);