diff options
Diffstat (limited to 'drivers/net/ethernet/wangxun')
-rw-r--r-- | drivers/net/ethernet/wangxun/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_ethtool.c | 224 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_ethtool.h | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_hw.c | 137 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_hw.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_lib.c | 113 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_sriov.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_type.h | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_vf.h | 72 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/libwx/wx_vf_lib.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c | 5 |
17 files changed, 536 insertions, 117 deletions
diff --git a/drivers/net/ethernet/wangxun/Kconfig b/drivers/net/ethernet/wangxun/Kconfig index 424ec3212128..d138dea7d208 100644 --- a/drivers/net/ethernet/wangxun/Kconfig +++ b/drivers/net/ethernet/wangxun/Kconfig @@ -20,6 +20,7 @@ config LIBWX tristate depends on PTP_1588_CLOCK_OPTIONAL select PAGE_POOL + select DIMLIB help Common library for Wangxun(R) Ethernet drivers. diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c index c12a4cb951f6..06f401bd975c 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c @@ -303,6 +303,11 @@ int wx_get_coalesce(struct net_device *netdev, else ec->rx_coalesce_usecs = wx->rx_itr_setting >> 2; + if (wx->adaptive_itr) { + ec->use_adaptive_rx_coalesce = 1; + ec->use_adaptive_tx_coalesce = 1; + } + /* if in mixed tx/rx queues per vector mode, report only rx settings */ if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count) return 0; @@ -334,19 +339,28 @@ int wx_set_coalesce(struct net_device *netdev, return -EOPNOTSUPP; } - if (ec->tx_max_coalesced_frames_irq) - wx->tx_work_limit = ec->tx_max_coalesced_frames_irq; + if (ec->tx_max_coalesced_frames_irq > U16_MAX || + !ec->tx_max_coalesced_frames_irq) + return -EINVAL; + + wx->tx_work_limit = ec->tx_max_coalesced_frames_irq; switch (wx->mac.type) { case wx_mac_sp: max_eitr = WX_SP_MAX_EITR; + rx_itr_param = WX_20K_ITR; + tx_itr_param = WX_12K_ITR; break; case wx_mac_aml: case wx_mac_aml40: max_eitr = WX_AML_MAX_EITR; + rx_itr_param = WX_20K_ITR; + tx_itr_param = WX_12K_ITR; break; default: max_eitr = WX_EM_MAX_EITR; + rx_itr_param = WX_7K_ITR; + tx_itr_param = WX_7K_ITR; break; } @@ -354,36 +368,37 @@ int wx_set_coalesce(struct net_device *netdev, (ec->tx_coalesce_usecs > (max_eitr >> 2))) return -EINVAL; + if (ec->use_adaptive_rx_coalesce) { + wx->adaptive_itr = true; + wx->rx_itr_setting = 1; + wx->tx_itr_setting = 1; + return 0; + } + if (ec->rx_coalesce_usecs > 1) wx->rx_itr_setting = ec->rx_coalesce_usecs << 2; else wx->rx_itr_setting = ec->rx_coalesce_usecs; - if (wx->rx_itr_setting == 1) - rx_itr_param = WX_20K_ITR; - else - rx_itr_param = wx->rx_itr_setting; - if (ec->tx_coalesce_usecs > 1) wx->tx_itr_setting = ec->tx_coalesce_usecs << 2; else wx->tx_itr_setting = ec->tx_coalesce_usecs; - if (wx->tx_itr_setting == 1) { - switch (wx->mac.type) { - case wx_mac_sp: - case wx_mac_aml: - case wx_mac_aml40: - tx_itr_param = WX_12K_ITR; - break; - default: - tx_itr_param = WX_20K_ITR; - break; - } - } else { - tx_itr_param = wx->tx_itr_setting; + if (wx->adaptive_itr) { + wx->adaptive_itr = false; + wx->rx_itr_setting = rx_itr_param; + wx->tx_itr_setting = tx_itr_param; + } else if (wx->rx_itr_setting == 1 || wx->tx_itr_setting == 1) { + wx->adaptive_itr = true; } + if (wx->rx_itr_setting != 1) + rx_itr_param = wx->rx_itr_setting; + + if (wx->tx_itr_setting != 1) + tx_itr_param = wx->tx_itr_setting; + /* mixed Rx/Tx */ if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count) wx->tx_itr_setting = wx->rx_itr_setting; @@ -466,6 +481,142 @@ int wx_set_channels(struct net_device *dev, } EXPORT_SYMBOL(wx_set_channels); +u32 wx_rss_indir_size(struct net_device *netdev) +{ + struct wx *wx = netdev_priv(netdev); + + return wx_rss_indir_tbl_entries(wx); +} +EXPORT_SYMBOL(wx_rss_indir_size); + +u32 wx_get_rxfh_key_size(struct net_device *netdev) +{ + return WX_RSS_KEY_SIZE; +} +EXPORT_SYMBOL(wx_get_rxfh_key_size); + +static void wx_get_reta(struct wx *wx, u32 *indir) +{ + u32 reta_size = wx_rss_indir_tbl_entries(wx); + u16 rss_m = wx->ring_feature[RING_F_RSS].mask; + + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags)) + rss_m = wx->ring_feature[RING_F_RSS].indices - 1; + + for (u32 i = 0; i < reta_size; i++) + indir[i] = wx->rss_indir_tbl[i] & rss_m; +} + +int wx_get_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh) +{ + struct wx *wx = netdev_priv(netdev); + + rxfh->hfunc = ETH_RSS_HASH_TOP; + + if (rxfh->indir) + wx_get_reta(wx, rxfh->indir); + + if (rxfh->key) + memcpy(rxfh->key, wx->rss_key, WX_RSS_KEY_SIZE); + + return 0; +} +EXPORT_SYMBOL(wx_get_rxfh); + +int wx_set_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + struct wx *wx = netdev_priv(netdev); + u32 reta_entries, i; + + if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && + rxfh->hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + reta_entries = wx_rss_indir_tbl_entries(wx); + /* Fill out the redirection table */ + if (rxfh->indir) { + for (i = 0; i < reta_entries; i++) + wx->rss_indir_tbl[i] = rxfh->indir[i]; + + wx_store_reta(wx); + } + + /* Fill out the rss hash key */ + if (rxfh->key) { + memcpy(wx->rss_key, rxfh->key, WX_RSS_KEY_SIZE); + wx_store_rsskey(wx); + } + + return 0; +} +EXPORT_SYMBOL(wx_set_rxfh); + +static const struct wx_rss_flow_map rss_flow_table[] = { + { TCP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_TCP }, + { TCP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_TCP }, + { UDP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_UDP }, + { UDP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_UDP }, + { SCTP_V4_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV4_SCTP }, + { SCTP_V6_FLOW, RXH_L4_B_0_1 | RXH_L4_B_2_3, WX_RSS_FIELD_IPV6_SCTP }, +}; + +int wx_get_rxfh_fields(struct net_device *dev, + struct ethtool_rxfh_fields *nfc) +{ + struct wx *wx = netdev_priv(dev); + + nfc->data = RXH_IP_SRC | RXH_IP_DST; + + for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) { + const struct wx_rss_flow_map *entry = &rss_flow_table[i]; + + if (entry->flow_type == nfc->flow_type) { + if (wx->rss_flags & entry->flag) + nfc->data |= entry->data; + break; + } + } + + return 0; +} +EXPORT_SYMBOL(wx_get_rxfh_fields); + +int wx_set_rxfh_fields(struct net_device *dev, + const struct ethtool_rxfh_fields *nfc, + struct netlink_ext_ack *extack) +{ + struct wx *wx = netdev_priv(dev); + u8 flags = wx->rss_flags; + + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + + for (u32 i = 0; i < ARRAY_SIZE(rss_flow_table); i++) { + const struct wx_rss_flow_map *entry = &rss_flow_table[i]; + + if (entry->flow_type == nfc->flow_type) { + if (nfc->data & entry->data) + flags |= entry->flag; + else + flags &= ~entry->flag; + + if (flags != wx->rss_flags) { + wx->rss_flags = flags; + wx_config_rss_field(wx); + } + + return 0; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL(wx_set_rxfh_fields); + u32 wx_get_msglevel(struct net_device *netdev) { struct wx *wx = netdev_priv(netdev); @@ -531,3 +682,36 @@ void wx_get_ptp_stats(struct net_device *dev, } } EXPORT_SYMBOL(wx_get_ptp_stats); + +static int wx_get_link_ksettings_vf(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + struct wx *wx = netdev_priv(netdev); + + ethtool_link_ksettings_zero_link_mode(cmd, supported); + cmd->base.autoneg = AUTONEG_DISABLE; + cmd->base.port = PORT_NONE; + cmd->base.duplex = DUPLEX_FULL; + cmd->base.speed = wx->speed; + + return 0; +} + +static const struct ethtool_ops wx_ethtool_ops_vf = { + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | + ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | + ETHTOOL_COALESCE_USE_ADAPTIVE, + .get_drvinfo = wx_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_ringparam = wx_get_ringparam, + .get_msglevel = wx_get_msglevel, + .get_coalesce = wx_get_coalesce, + .get_ts_info = ethtool_op_get_ts_info, + .get_link_ksettings = wx_get_link_ksettings_vf, +}; + +void wx_set_ethtool_ops_vf(struct net_device *netdev) +{ + netdev->ethtool_ops = &wx_ethtool_ops_vf; +} +EXPORT_SYMBOL(wx_set_ethtool_ops_vf); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h index 9e002e699eca..727093970462 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.h @@ -38,10 +38,23 @@ void wx_get_channels(struct net_device *dev, struct ethtool_channels *ch); int wx_set_channels(struct net_device *dev, struct ethtool_channels *ch); +u32 wx_rss_indir_size(struct net_device *netdev); +u32 wx_get_rxfh_key_size(struct net_device *netdev); +int wx_get_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh); +int wx_set_rxfh(struct net_device *netdev, + struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack); +int wx_get_rxfh_fields(struct net_device *dev, + struct ethtool_rxfh_fields *cmd); +int wx_set_rxfh_fields(struct net_device *dev, + const struct ethtool_rxfh_fields *nfc, + struct netlink_ext_ack *extack); u32 wx_get_msglevel(struct net_device *netdev); void wx_set_msglevel(struct net_device *netdev, u32 data); int wx_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info); void wx_get_ptp_stats(struct net_device *dev, struct ethtool_ts_stats *ts_stats); +void wx_set_ethtool_ops_vf(struct net_device *netdev); #endif /* _WX_ETHTOOL_H_ */ diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index bcd07a715752..1e2713f0c921 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -1998,8 +1998,17 @@ static void wx_restore_vlan(struct wx *wx) wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), vid); } -static void wx_store_reta(struct wx *wx) +u32 wx_rss_indir_tbl_entries(struct wx *wx) { + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags)) + return 64; + else + return 128; +} + +void wx_store_reta(struct wx *wx) +{ + u32 reta_entries = wx_rss_indir_tbl_entries(wx); u8 *indir_tbl = wx->rss_indir_tbl; u32 reta = 0; u32 i; @@ -2007,45 +2016,110 @@ static void wx_store_reta(struct wx *wx) /* Fill out the redirection table as follows: * - 8 bit wide entries containing 4 bit RSS index */ - for (i = 0; i < WX_MAX_RETA_ENTRIES; i++) { + for (i = 0; i < reta_entries; i++) { reta |= indir_tbl[i] << (i & 0x3) * 8; if ((i & 3) == 3) { - wr32(wx, WX_RDB_RSSTBL(i >> 2), reta); + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) && + test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) + wr32(wx, WX_RDB_VMRSSTBL(i >> 2, wx->num_vfs), reta); + else + wr32(wx, WX_RDB_RSSTBL(i >> 2), reta); reta = 0; } } } -static void wx_setup_reta(struct wx *wx) +void wx_store_rsskey(struct wx *wx) { - u16 rss_i = wx->ring_feature[RING_F_RSS].indices; - u32 random_key_size = WX_RSS_KEY_SIZE / 4; - u32 i, j; + u32 key_size = WX_RSS_KEY_SIZE / 4; + u32 i; - if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags)) { - if (wx->mac.type == wx_mac_em) - rss_i = 1; - else - rss_i = rss_i < 4 ? 4 : rss_i; + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) && + test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { + for (i = 0; i < key_size; i++) + wr32(wx, WX_RDB_VMRSSRK(i, wx->num_vfs), + wx->rss_key[i]); + } else { + for (i = 0; i < key_size; i++) + wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]); } +} +static void wx_setup_reta(struct wx *wx) +{ /* Fill out hash function seeds */ - for (i = 0; i < random_key_size; i++) - wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]); + wx_store_rsskey(wx); /* Fill out redirection table */ - memset(wx->rss_indir_tbl, 0, sizeof(wx->rss_indir_tbl)); + if (!netif_is_rxfh_configured(wx->netdev)) { + u16 rss_i = wx->ring_feature[RING_F_RSS].indices; + u32 reta_entries = wx_rss_indir_tbl_entries(wx); + u32 i, j; + + memset(wx->rss_indir_tbl, 0, sizeof(wx->rss_indir_tbl)); + + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags)) { + if (test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) + rss_i = rss_i < 2 ? 2 : rss_i; + else + rss_i = 1; + } - for (i = 0, j = 0; i < WX_MAX_RETA_ENTRIES; i++, j++) { - if (j == rss_i) - j = 0; + for (i = 0, j = 0; i < reta_entries; i++, j++) { + if (j == rss_i) + j = 0; - wx->rss_indir_tbl[i] = j; + wx->rss_indir_tbl[i] = j; + } } wx_store_reta(wx); } +void wx_config_rss_field(struct wx *wx) +{ + u32 rss_field; + + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) && + test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { + rss_field = rd32(wx, WX_RDB_PL_CFG(wx->num_vfs)); + rss_field &= ~WX_RDB_PL_CFG_RSS_MASK; + rss_field |= FIELD_PREP(WX_RDB_PL_CFG_RSS_MASK, wx->rss_flags); + wr32(wx, WX_RDB_PL_CFG(wx->num_vfs), rss_field); + + /* Enable global RSS and multiple RSS to make the RSS + * field of each pool take effect. + */ + wr32m(wx, WX_RDB_RA_CTL, + WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN, + WX_RDB_RA_CTL_MULTI_RSS | WX_RDB_RA_CTL_RSS_EN); + } else { + rss_field = rd32(wx, WX_RDB_RA_CTL); + rss_field &= ~WX_RDB_RA_CTL_RSS_MASK; + rss_field |= FIELD_PREP(WX_RDB_RA_CTL_RSS_MASK, wx->rss_flags); + wr32(wx, WX_RDB_RA_CTL, rss_field); + } +} + +void wx_enable_rss(struct wx *wx, bool enable) +{ + if (test_bit(WX_FLAG_SRIOV_ENABLED, wx->flags) && + test_bit(WX_FLAG_MULTI_64_FUNC, wx->flags)) { + if (enable) + wr32m(wx, WX_RDB_PL_CFG(wx->num_vfs), + WX_RDB_PL_CFG_RSS_EN, WX_RDB_PL_CFG_RSS_EN); + else + wr32m(wx, WX_RDB_PL_CFG(wx->num_vfs), + WX_RDB_PL_CFG_RSS_EN, 0); + } else { + if (enable) + wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, + WX_RDB_RA_CTL_RSS_EN); + else + wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0); + } +} + #define WX_RDB_RSS_PL_2 FIELD_PREP(GENMASK(31, 29), 1) #define WX_RDB_RSS_PL_4 FIELD_PREP(GENMASK(31, 29), 2) static void wx_setup_psrtype(struct wx *wx) @@ -2076,31 +2150,12 @@ static void wx_setup_psrtype(struct wx *wx) static void wx_setup_mrqc(struct wx *wx) { - u32 rss_field = 0; - - /* VT, and RSS do not coexist at the same time */ - if (test_bit(WX_FLAG_VMDQ_ENABLED, wx->flags)) - return; - /* Disable indicating checksum in descriptor, enables RSS hash */ wr32m(wx, WX_PSR_CTL, WX_PSR_CTL_PCSD, WX_PSR_CTL_PCSD); - /* Perform hash on these packet types */ - rss_field = WX_RDB_RA_CTL_RSS_IPV4 | - WX_RDB_RA_CTL_RSS_IPV4_TCP | - WX_RDB_RA_CTL_RSS_IPV4_UDP | - WX_RDB_RA_CTL_RSS_IPV6 | - WX_RDB_RA_CTL_RSS_IPV6_TCP | - WX_RDB_RA_CTL_RSS_IPV6_UDP; - - netdev_rss_key_fill(wx->rss_key, sizeof(wx->rss_key)); - + wx_config_rss_field(wx); + wx_enable_rss(wx, wx->rss_enabled); wx_setup_reta(wx); - - if (wx->rss_enabled) - rss_field |= WX_RDB_RA_CTL_RSS_EN; - - wr32(wx, WX_RDB_RA_CTL, rss_field); } /** @@ -2393,6 +2448,8 @@ int wx_sw_init(struct wx *wx) wx_err(wx, "rss key allocation failed\n"); return err; } + wx->rss_flags = WX_RSS_FIELD_IPV4 | WX_RSS_FIELD_IPV4_TCP | + WX_RSS_FIELD_IPV6 | WX_RSS_FIELD_IPV6_TCP; wx->mac_table = kcalloc(wx->mac.num_rar_entries, sizeof(struct wx_mac_addr), diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.h b/drivers/net/ethernet/wangxun/libwx/wx_hw.h index 2393a743b564..13857376bbad 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.h @@ -39,6 +39,11 @@ void wx_set_rx_mode(struct net_device *netdev); int wx_change_mtu(struct net_device *netdev, int new_mtu); void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring); void wx_enable_rx_queue(struct wx *wx, struct wx_ring *ring); +u32 wx_rss_indir_tbl_entries(struct wx *wx); +void wx_store_reta(struct wx *wx); +void wx_store_rsskey(struct wx *wx); +void wx_config_rss_field(struct wx *wx); +void wx_enable_rss(struct wx *wx, bool enable); void wx_configure_rx(struct wx *wx); void wx_configure(struct wx *wx); void wx_start_hw(struct wx *wx); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index 723785ef87bb..3adf7048320a 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -16,6 +16,7 @@ #include "wx_lib.h" #include "wx_ptp.h" #include "wx_hw.h" +#include "wx_vf_lib.h" /* Lookup table mapping the HW PTYPE to the bit field for decoding */ static struct wx_dec_ptype wx_ptype_lookup[256] = { @@ -832,6 +833,36 @@ static bool wx_clean_tx_irq(struct wx_q_vector *q_vector, return !!budget; } +static void wx_update_rx_dim_sample(struct wx_q_vector *q_vector) +{ + struct dim_sample sample = {}; + + dim_update_sample(q_vector->total_events, + q_vector->rx.total_packets, + q_vector->rx.total_bytes, + &sample); + + net_dim(&q_vector->rx.dim, &sample); +} + +static void wx_update_tx_dim_sample(struct wx_q_vector *q_vector) +{ + struct dim_sample sample = {}; + + dim_update_sample(q_vector->total_events, + q_vector->tx.total_packets, + q_vector->tx.total_bytes, + &sample); + + net_dim(&q_vector->tx.dim, &sample); +} + +static void wx_update_dim_sample(struct wx_q_vector *q_vector) +{ + wx_update_rx_dim_sample(q_vector); + wx_update_tx_dim_sample(q_vector); +} + /** * wx_poll - NAPI polling RX/TX cleanup routine * @napi: napi struct with our devices info in it @@ -878,6 +909,8 @@ static int wx_poll(struct napi_struct *napi, int budget) /* all work done, exit the polling mode */ if (likely(napi_complete_done(napi, work_done))) { + if (wx->adaptive_itr) + wx_update_dim_sample(q_vector); if (netif_running(wx->netdev)) wx_intr_enable(wx, WX_INTR_Q(q_vector->v_idx)); } @@ -1591,6 +1624,65 @@ netdev_tx_t wx_xmit_frame(struct sk_buff *skb, } EXPORT_SYMBOL(wx_xmit_frame); +static void wx_set_itr(struct wx_q_vector *q_vector) +{ + struct wx *wx = q_vector->wx; + u32 new_itr; + + if (!wx->adaptive_itr) + return; + + /* use the smallest value of new ITR delay calculations */ + new_itr = min(q_vector->rx.itr, q_vector->tx.itr); + new_itr <<= 2; + + if (new_itr != q_vector->itr) { + /* save the algorithm value here */ + q_vector->itr = new_itr; + + if (wx->pdev->is_virtfn) + wx_write_eitr_vf(q_vector); + else + wx_write_eitr(q_vector); + } +} + +static void wx_rx_dim_work(struct work_struct *work) +{ + struct dim *dim = container_of(work, struct dim, work); + struct dim_cq_moder rx_moder; + struct wx_ring_container *rx; + struct wx_q_vector *q_vector; + + rx = container_of(dim, struct wx_ring_container, dim); + + rx_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); + rx->itr = rx_moder.usec; + + q_vector = container_of(rx, struct wx_q_vector, rx); + wx_set_itr(q_vector); + + dim->state = DIM_START_MEASURE; +} + +static void wx_tx_dim_work(struct work_struct *work) +{ + struct dim *dim = container_of(work, struct dim, work); + struct dim_cq_moder tx_moder; + struct wx_ring_container *tx; + struct wx_q_vector *q_vector; + + tx = container_of(dim, struct wx_ring_container, dim); + + tx_moder = net_dim_get_tx_moderation(dim->mode, dim->profile_ix); + tx->itr = tx_moder.usec; + + q_vector = container_of(tx, struct wx_q_vector, tx); + wx_set_itr(q_vector); + + dim->state = DIM_START_MEASURE; +} + void wx_napi_enable_all(struct wx *wx) { struct wx_q_vector *q_vector; @@ -1598,6 +1690,11 @@ void wx_napi_enable_all(struct wx *wx) for (q_idx = 0; q_idx < wx->num_q_vectors; q_idx++) { q_vector = wx->q_vector[q_idx]; + + INIT_WORK(&q_vector->rx.dim.work, wx_rx_dim_work); + INIT_WORK(&q_vector->tx.dim.work, wx_tx_dim_work); + q_vector->rx.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE; + q_vector->tx.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE; napi_enable(&q_vector->napi); } } @@ -1611,6 +1708,8 @@ void wx_napi_disable_all(struct wx *wx) for (q_idx = 0; q_idx < wx->num_q_vectors; q_idx++) { q_vector = wx->q_vector[q_idx]; napi_disable(&q_vector->napi); + disable_work_sync(&q_vector->rx.dim.work); + disable_work_sync(&q_vector->tx.dim.work); } } EXPORT_SYMBOL(wx_napi_disable_all); @@ -2197,8 +2296,10 @@ irqreturn_t wx_msix_clean_rings(int __always_unused irq, void *data) struct wx_q_vector *q_vector = data; /* EIAM disabled interrupts (on this vector) for us */ - if (q_vector->rx.ring || q_vector->tx.ring) + if (q_vector->rx.ring || q_vector->tx.ring) { napi_schedule_irqoff(&q_vector->napi); + q_vector->total_events++; + } return IRQ_HANDLED; } @@ -2915,14 +3016,8 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features) struct wx *wx = netdev_priv(netdev); bool need_reset = false; - if (features & NETIF_F_RXHASH) { - wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, - WX_RDB_RA_CTL_RSS_EN); - wx->rss_enabled = true; - } else { - wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0); - wx->rss_enabled = false; - } + wx->rss_enabled = !!(features & NETIF_F_RXHASH); + wx_enable_rss(wx, wx->rss_enabled); netdev->features = features; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c index c82ae137756c..c6d158cd70da 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c @@ -150,6 +150,12 @@ static int wx_pci_sriov_enable(struct pci_dev *dev, struct wx *wx = pci_get_drvdata(dev); int err = 0, i; + if (netif_is_rxfh_configured(wx->netdev)) { + wx_err(wx, "Cannot enable SR-IOV while RXFH is configured\n"); + wx_err(wx, "Run 'ethtool -X <if> default' to reset RSS table\n"); + return -EBUSY; + } + err = __wx_enable_sriov(wx, num_vfs); if (err) return err; @@ -173,12 +179,20 @@ err_out: return err; } -static void wx_pci_sriov_disable(struct pci_dev *dev) +static int wx_pci_sriov_disable(struct pci_dev *dev) { struct wx *wx = pci_get_drvdata(dev); + if (netif_is_rxfh_configured(wx->netdev)) { + wx_err(wx, "Cannot disable SR-IOV while RXFH is configured\n"); + wx_err(wx, "Run 'ethtool -X <if> default' to reset RSS table\n"); + return -EBUSY; + } + wx_disable_sriov(wx); wx_sriov_reinit(wx); + + return 0; } int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) @@ -187,10 +201,8 @@ int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) int err; if (!num_vfs) { - if (!pci_vfs_assigned(pdev)) { - wx_pci_sriov_disable(pdev); - return 0; - } + if (!pci_vfs_assigned(pdev)) + return wx_pci_sriov_disable(pdev); wx_err(wx, "can't free VFs because some are assigned to VMs.\n"); return -EBUSY; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index 9d5d10f9e410..d89b9b8a0a2c 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -10,6 +10,7 @@ #include <linux/netdevice.h> #include <linux/if_vlan.h> #include <linux/phylink.h> +#include <linux/dim.h> #include <net/ip.h> #define WX_NCSI_SUP 0x8000 @@ -167,9 +168,12 @@ #define WX_RDB_PL_CFG_L2HDR BIT(3) #define WX_RDB_PL_CFG_TUN_TUNHDR BIT(4) #define WX_RDB_PL_CFG_TUN_OUTL2HDR BIT(5) +#define WX_RDB_PL_CFG_RSS_EN BIT(24) +#define WX_RDB_PL_CFG_RSS_MASK GENMASK(23, 16) #define WX_RDB_RSSTBL(_i) (0x19400 + ((_i) * 4)) #define WX_RDB_RSSRK(_i) (0x19480 + ((_i) * 4)) #define WX_RDB_RA_CTL 0x194F4 +#define WX_RDB_RA_CTL_MULTI_RSS BIT(0) #define WX_RDB_RA_CTL_RSS_EN BIT(2) /* RSS Enable */ #define WX_RDB_RA_CTL_RSS_IPV4_TCP BIT(16) #define WX_RDB_RA_CTL_RSS_IPV4 BIT(17) @@ -177,8 +181,12 @@ #define WX_RDB_RA_CTL_RSS_IPV6_TCP BIT(21) #define WX_RDB_RA_CTL_RSS_IPV4_UDP BIT(22) #define WX_RDB_RA_CTL_RSS_IPV6_UDP BIT(23) +#define WX_RDB_RA_CTL_RSS_MASK GENMASK(23, 16) #define WX_RDB_FDIR_MATCH 0x19558 #define WX_RDB_FDIR_MISS 0x1955C +/* VM RSS */ +#define WX_RDB_VMRSSRK(_i, _p) (0x1A000 + ((_i) * 4) + ((_p) * 0x40)) +#define WX_RDB_VMRSSTBL(_i, _p) (0x1B000 + ((_i) * 4) + ((_p) * 0x40)) /******************************* PSR Registers *******************************/ /* psr control */ @@ -1033,6 +1041,7 @@ struct wx_ring_container { unsigned int total_packets; /* total packets processed this int */ u8 count; /* total number of rings in vector */ u8 itr; /* current ITR setting for ring */ + struct dim dim; /* data for net_dim algorithm */ }; struct wx_ring { struct wx_ring *next; /* pointer to next ring in q_vector */ @@ -1089,6 +1098,8 @@ struct wx_q_vector { struct napi_struct napi; struct rcu_head rcu; /* to avoid race with update stats on free */ + u16 total_events; /* number of interrupts processed */ + char name[IFNAMSIZ + 17]; /* for dynamic allocation of rings associated with this q_vector */ @@ -1188,6 +1199,21 @@ struct vf_macvlans { u8 vf_macvlan[ETH_ALEN]; }; +#define WX_RSS_FIELD_IPV4_TCP BIT(0) +#define WX_RSS_FIELD_IPV4 BIT(1) +#define WX_RSS_FIELD_IPV4_SCTP BIT(2) +#define WX_RSS_FIELD_IPV6_SCTP BIT(3) +#define WX_RSS_FIELD_IPV6_TCP BIT(4) +#define WX_RSS_FIELD_IPV6 BIT(5) +#define WX_RSS_FIELD_IPV4_UDP BIT(6) +#define WX_RSS_FIELD_IPV6_UDP BIT(7) + +struct wx_rss_flow_map { + u8 flow_type; + u32 data; + u8 flag; +}; + enum wx_pf_flags { WX_FLAG_MULTI_64_FUNC, WX_FLAG_SWFW_RING, @@ -1268,6 +1294,7 @@ struct wx { int num_rx_queues; u16 rx_itr_setting; u16 rx_work_limit; + bool adaptive_itr; int num_q_vectors; /* current number of q_vectors for device */ int max_q_vectors; /* upper limit of q_vectors for device */ @@ -1297,6 +1324,7 @@ struct wx { #define WX_MAX_RETA_ENTRIES 128 #define WX_RSS_INDIR_TBL_MAX 64 u8 rss_indir_tbl[WX_MAX_RETA_ENTRIES]; + u8 rss_flags; bool rss_enabled; #define WX_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ u32 *rss_key; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf.h b/drivers/net/ethernet/wangxun/libwx/wx_vf.h index fec1126703e3..3f16de0fa427 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf.h @@ -4,6 +4,7 @@ #ifndef _WX_VF_H_ #define _WX_VF_H_ +/* Control registers */ #define WX_VF_MAX_RING_NUMS 8 #define WX_VX_PF_BME 0x4B8 #define WX_VF_BME_ENABLE BIT(0) @@ -12,16 +13,32 @@ #define WX_VXCTRL_RST BIT(0) #define WX_VXMRQC 0x78 +#define WX_VXMRQC_PSR_L4HDR BIT(0) +#define WX_VXMRQC_PSR_L3HDR BIT(1) +#define WX_VXMRQC_PSR_L2HDR BIT(2) +#define WX_VXMRQC_PSR_TUNHDR BIT(3) +#define WX_VXMRQC_PSR_TUNMAC BIT(4) +#define WX_VXMRQC_PSR_MASK GENMASK(5, 1) +#define WX_VXMRQC_PSR(f) FIELD_PREP(GENMASK(5, 1), f) +#define WX_VXMRQC_RSS_HASH(f) FIELD_PREP(GENMASK(15, 13), f) +#define WX_VXMRQC_RSS_MASK GENMASK(31, 16) +#define WX_VXMRQC_RSS(f) FIELD_PREP(GENMASK(31, 16), f) +#define WX_VXMRQC_RSS_ALG_IPV4_TCP BIT(0) +#define WX_VXMRQC_RSS_ALG_IPV4 BIT(1) +#define WX_VXMRQC_RSS_ALG_IPV6 BIT(4) +#define WX_VXMRQC_RSS_ALG_IPV6_TCP BIT(5) +#define WX_VXMRQC_RSS_EN BIT(8) + +#define WX_VXRSSRK(i) (0x80 + ((i) * 4)) /* i=[0,9] */ +#define WX_VXRETA(i) (0xC0 + ((i) * 4)) /* i=[0,15] */ + +/* Interrupt registers */ #define WX_VXICR 0x100 #define WX_VXIMS 0x108 #define WX_VXIMC 0x10C #define WX_VF_IRQ_CLEAR_MASK 7 #define WX_VF_MAX_TX_QUEUES 4 #define WX_VF_MAX_RX_QUEUES 4 -#define WX_VXTXDCTL(r) (0x3010 + (0x40 * (r))) -#define WX_VXRXDCTL(r) (0x1010 + (0x40 * (r))) -#define WX_VXRXDCTL_ENABLE BIT(0) -#define WX_VXTXDCTL_FLUSH BIT(26) #define WX_VXITR(i) (0x200 + (4 * (i))) /* i=[0,1] */ #define WX_VXITR_MASK GENMASK(8, 0) @@ -29,16 +46,6 @@ #define WX_VXIVAR_MISC 0x260 #define WX_VXIVAR(i) (0x240 + (4 * (i))) /* i=[0,3] */ -#define WX_VXRXDCTL_RSCMAX(f) FIELD_PREP(GENMASK(24, 23), f) -#define WX_VXRXDCTL_BUFLEN(f) FIELD_PREP(GENMASK(6, 1), f) -#define WX_VXRXDCTL_BUFSZ(f) FIELD_PREP(GENMASK(11, 8), f) -#define WX_VXRXDCTL_HDRSZ(f) FIELD_PREP(GENMASK(15, 12), f) - -#define WX_VXRXDCTL_RSCMAX_MASK GENMASK(24, 23) -#define WX_VXRXDCTL_BUFLEN_MASK GENMASK(6, 1) -#define WX_VXRXDCTL_BUFSZ_MASK GENMASK(11, 8) -#define WX_VXRXDCTL_HDRSZ_MASK GENMASK(15, 12) - #define wx_conf_size(v, mwidth, uwidth) ({ \ typeof(v) _v = (v); \ (_v == 2 << (mwidth) ? 0 : _v >> (uwidth)); \ @@ -59,44 +66,35 @@ #define WX_VXRDBAH(r) (0x1004 + (0x40 * (r))) #define WX_VXRDT(r) (0x1008 + (0x40 * (r))) #define WX_VXRDH(r) (0x100C + (0x40 * (r))) - +#define WX_VXRXDCTL(r) (0x1010 + (0x40 * (r))) +#define WX_VXRXDCTL_ENABLE BIT(0) +#define WX_VXRXDCTL_BUFLEN_MASK GENMASK(6, 1) +#define WX_VXRXDCTL_BUFLEN(f) FIELD_PREP(GENMASK(6, 1), f) +#define WX_VXRXDCTL_BUFSZ_MASK GENMASK(11, 8) +#define WX_VXRXDCTL_BUFSZ(f) FIELD_PREP(GENMASK(11, 8), f) +#define WX_VXRXDCTL_HDRSZ_MASK GENMASK(15, 12) +#define WX_VXRXDCTL_HDRSZ(f) FIELD_PREP(GENMASK(15, 12), f) +#define WX_VXRXDCTL_RSCMAX_MASK GENMASK(24, 23) +#define WX_VXRXDCTL_RSCMAX(f) FIELD_PREP(GENMASK(24, 23), f) #define WX_VXRXDCTL_RSCEN BIT(29) #define WX_VXRXDCTL_DROP BIT(30) #define WX_VXRXDCTL_VLAN BIT(31) +/* Transimit Path */ #define WX_VXTDBAL(r) (0x3000 + (0x40 * (r))) #define WX_VXTDBAH(r) (0x3004 + (0x40 * (r))) #define WX_VXTDT(r) (0x3008 + (0x40 * (r))) #define WX_VXTDH(r) (0x300C + (0x40 * (r))) - +#define WX_VXTXDCTL(r) (0x3010 + (0x40 * (r))) #define WX_VXTXDCTL_ENABLE BIT(0) #define WX_VXTXDCTL_BUFLEN(f) FIELD_PREP(GENMASK(6, 1), f) #define WX_VXTXDCTL_PTHRESH(f) FIELD_PREP(GENMASK(11, 8), f) #define WX_VXTXDCTL_WTHRESH(f) FIELD_PREP(GENMASK(22, 16), f) - -#define WX_VXMRQC_PSR(f) FIELD_PREP(GENMASK(5, 1), f) -#define WX_VXMRQC_PSR_MASK GENMASK(5, 1) -#define WX_VXMRQC_PSR_L4HDR BIT(0) -#define WX_VXMRQC_PSR_L3HDR BIT(1) -#define WX_VXMRQC_PSR_L2HDR BIT(2) -#define WX_VXMRQC_PSR_TUNHDR BIT(3) -#define WX_VXMRQC_PSR_TUNMAC BIT(4) - -#define WX_VXRSSRK(i) (0x80 + ((i) * 4)) /* i=[0,9] */ -#define WX_VXRETA(i) (0xC0 + ((i) * 4)) /* i=[0,15] */ - -#define WX_VXMRQC_RSS(f) FIELD_PREP(GENMASK(31, 16), f) -#define WX_VXMRQC_RSS_MASK GENMASK(31, 16) -#define WX_VXMRQC_RSS_ALG_IPV4_TCP BIT(0) -#define WX_VXMRQC_RSS_ALG_IPV4 BIT(1) -#define WX_VXMRQC_RSS_ALG_IPV6 BIT(4) -#define WX_VXMRQC_RSS_ALG_IPV6_TCP BIT(5) -#define WX_VXMRQC_RSS_EN BIT(8) -#define WX_VXMRQC_RSS_HASH(f) FIELD_PREP(GENMASK(15, 13), f) +#define WX_VXTXDCTL_FLUSH BIT(26) #define WX_PFLINK_STATUS(g) FIELD_GET(BIT(0), g) #define WX_PFLINK_SPEED(g) FIELD_GET(GENMASK(31, 1), g) -#define WX_VXSTATUS_SPEED(g) FIELD_GET(GENMASK(4, 1), g) +#define WX_VXSTATUS_SPEED(g) FIELD_GET(GENMASK(4, 1), g) struct wx_link_reg_fields { u32 mac_type; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c index 3023ea2732ef..a87887b9f8ee 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c @@ -10,7 +10,7 @@ #include "wx_vf.h" #include "wx_vf_lib.h" -static void wx_write_eitr_vf(struct wx_q_vector *q_vector) +void wx_write_eitr_vf(struct wx_q_vector *q_vector) { struct wx *wx = q_vector->wx; int v_idx = q_vector->v_idx; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.h b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.h index 43ea126b79eb..a4bd23c92800 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.h @@ -4,6 +4,7 @@ #ifndef _WX_VF_LIB_H_ #define _WX_VF_LIB_H_ +void wx_write_eitr_vf(struct wx_q_vector *q_vector); void wx_configure_msix_vf(struct wx *wx); int wx_write_uc_addr_list_vf(struct net_device *netdev); void wx_setup_psrtype_vf(struct wx *wx); diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c index 7e2d9ec38a30..662f28bdde8a 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c @@ -115,7 +115,8 @@ static int ngbe_set_channels(struct net_device *dev, static const struct ethtool_ops ngbe_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | - ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, + ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | + ETHTOOL_COALESCE_USE_ADAPTIVE, .get_drvinfo = wx_get_drvinfo, .get_link = ethtool_op_get_link, .get_link_ksettings = wx_get_link_ksettings, @@ -136,6 +137,12 @@ static const struct ethtool_ops ngbe_ethtool_ops = { .set_coalesce = wx_set_coalesce, .get_channels = wx_get_channels, .set_channels = ngbe_set_channels, + .get_rxfh_fields = wx_get_rxfh_fields, + .set_rxfh_fields = wx_set_rxfh_fields, + .get_rxfh_indir_size = wx_rss_indir_size, + .get_rxfh_key_size = wx_get_rxfh_key_size, + .get_rxfh = wx_get_rxfh, + .set_rxfh = wx_set_rxfh, .get_msglevel = wx_get_msglevel, .set_msglevel = wx_set_msglevel, .get_ts_info = wx_get_ts_info, diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c index e0fc897b0a58..58488e138beb 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c @@ -119,9 +119,9 @@ static int ngbe_sw_init(struct wx *wx) num_online_cpus()); wx->rss_enabled = true; - /* enable itr by default in dynamic mode */ - wx->rx_itr_setting = 1; - wx->tx_itr_setting = 1; + wx->adaptive_itr = false; + wx->rx_itr_setting = WX_7K_ITR; + wx->tx_itr_setting = WX_7K_ITR; /* set default ring sizes */ wx->tx_ring_count = NGBE_DEFAULT_TXD; diff --git a/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c b/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c index c1246ab5239c..6ef43adcc425 100644 --- a/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c +++ b/drivers/net/ethernet/wangxun/ngbevf/ngbevf_main.c @@ -14,6 +14,7 @@ #include "../libwx/wx_mbx.h" #include "../libwx/wx_vf.h" #include "../libwx/wx_vf_common.h" +#include "../libwx/wx_ethtool.h" #include "ngbevf_type.h" /* ngbevf_pci_tbl - PCI Device ID Table @@ -100,6 +101,7 @@ static int ngbevf_sw_init(struct wx *wx) wx->mac.max_tx_queues = NGBEVF_MAX_TX_QUEUES; wx->mac.max_rx_queues = NGBEVF_MAX_RX_QUEUES; /* Enable dynamic interrupt throttling rates */ + wx->adaptive_itr = true; wx->rx_itr_setting = 1; wx->tx_itr_setting = 1; /* set default ring sizes */ @@ -185,6 +187,8 @@ static int ngbevf_probe(struct pci_dev *pdev, goto err_pci_release_regions; } + wx->driver_name = KBUILD_MODNAME; + wx_set_ethtool_ops_vf(netdev); netdev->netdev_ops = &ngbevf_netdev_ops; /* setup the private structure */ @@ -202,6 +206,7 @@ static int ngbevf_probe(struct pci_dev *pdev, if (err) goto err_free_sw_init; + wx_get_fw_version_vf(wx); err = register_netdev(netdev); if (err) goto err_register; diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c index a4753402660e..e285b088c7b2 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c @@ -538,7 +538,8 @@ static int txgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) static const struct ethtool_ops txgbe_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | - ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, + ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | + ETHTOOL_COALESCE_USE_ADAPTIVE, .get_drvinfo = wx_get_drvinfo, .nway_reset = wx_nway_reset, .get_link = ethtool_op_get_link, @@ -559,6 +560,12 @@ static const struct ethtool_ops txgbe_ethtool_ops = { .set_channels = txgbe_set_channels, .get_rxnfc = txgbe_get_rxnfc, .set_rxnfc = txgbe_set_rxnfc, + .get_rxfh_fields = wx_get_rxfh_fields, + .set_rxfh_fields = wx_set_rxfh_fields, + .get_rxfh_indir_size = wx_rss_indir_size, + .get_rxfh_key_size = wx_get_rxfh_key_size, + .get_rxfh = wx_get_rxfh, + .set_rxfh = wx_set_rxfh, .get_msglevel = wx_get_msglevel, .set_msglevel = wx_set_msglevel, .get_ts_info = wx_get_ts_info, diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index a5867f3c93fc..c4c4d70d8466 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -401,6 +401,7 @@ static int txgbe_sw_init(struct wx *wx) set_bit(WX_FLAG_MULTI_64_FUNC, wx->flags); /* enable itr by default in dynamic mode */ + wx->adaptive_itr = true; wx->rx_itr_setting = 1; wx->tx_itr_setting = 1; diff --git a/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c b/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c index ebfce3cf753e..72663e3c4205 100644 --- a/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c +++ b/drivers/net/ethernet/wangxun/txgbevf/txgbevf_main.c @@ -14,6 +14,7 @@ #include "../libwx/wx_mbx.h" #include "../libwx/wx_vf.h" #include "../libwx/wx_vf_common.h" +#include "../libwx/wx_ethtool.h" #include "txgbevf_type.h" /* txgbevf_pci_tbl - PCI Device ID Table @@ -144,6 +145,7 @@ static int txgbevf_sw_init(struct wx *wx) wx->mac.max_tx_queues = TXGBEVF_MAX_TX_QUEUES; wx->mac.max_rx_queues = TXGBEVF_MAX_RX_QUEUES; /* Enable dynamic interrupt throttling rates */ + wx->adaptive_itr = true; wx->rx_itr_setting = 1; wx->tx_itr_setting = 1; /* set default ring sizes */ @@ -238,6 +240,8 @@ static int txgbevf_probe(struct pci_dev *pdev, goto err_pci_release_regions; } + wx->driver_name = KBUILD_MODNAME; + wx_set_ethtool_ops_vf(netdev); netdev->netdev_ops = &txgbevf_netdev_ops; /* setup the private structure */ @@ -255,6 +259,7 @@ static int txgbevf_probe(struct pci_dev *pdev, if (err) goto err_free_sw_init; + wx_get_fw_version_vf(wx); err = register_netdev(netdev); if (err) goto err_register; |