Commit c424d4a3 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

i40e/i40evf: Add legacy-rx private flag to allow fallback to old Rx flow

This patch adds a control which will allow us to toggle into and out of the
legacy Rx mode.  The legacy Rx mode is what we currently do when performing
Rx.  As I make further changes what should happen is that the driver will
fall back to the behavior for Rx as of this patch should the "legacy-rx"
flag be set to on.

Change-ID: I0342998849bbb31351cce05f6e182c99174e7751
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent fa2343e9
...@@ -430,6 +430,7 @@ struct i40e_pf { ...@@ -430,6 +430,7 @@ struct i40e_pf {
#define I40E_FLAG_TEMP_LINK_POLLING BIT_ULL(55) #define I40E_FLAG_TEMP_LINK_POLLING BIT_ULL(55)
#define I40E_FLAG_CLIENT_L2_CHANGE BIT_ULL(56) #define I40E_FLAG_CLIENT_L2_CHANGE BIT_ULL(56)
#define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(57) #define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(57)
#define I40E_FLAG_LEGACY_RX BIT_ULL(58)
/* Tracks features that are disabled due to hw limitations. /* Tracks features that are disabled due to hw limitations.
* If a bit is set here, it means that the corresponding * If a bit is set here, it means that the corresponding
......
...@@ -226,6 +226,7 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = { ...@@ -226,6 +226,7 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0), I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0), I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0), I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0),
I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0),
}; };
#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags) #define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
...@@ -4055,6 +4056,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) ...@@ -4055,6 +4056,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
} }
flags_complete: flags_complete:
/* check for flags that changed */
changed_flags ^= pf->flags; changed_flags ^= pf->flags;
/* Process any additional changes needed as a result of flag changes. /* Process any additional changes needed as a result of flag changes.
...@@ -4095,7 +4097,8 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) ...@@ -4095,7 +4097,8 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
/* Issue reset to cause things to take effect, as additional bits /* Issue reset to cause things to take effect, as additional bits
* are added we will need to create a mask of bits requiring reset * are added we will need to create a mask of bits requiring reset
*/ */
if (changed_flags & I40E_FLAG_VEB_STATS_ENABLED) if ((changed_flags & I40E_FLAG_VEB_STATS_ENABLED) ||
((changed_flags & I40E_FLAG_LEGACY_RX) && netif_running(dev)))
i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED)); i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED));
return 0; return 0;
......
...@@ -222,6 +222,7 @@ struct i40evf_adapter { ...@@ -222,6 +222,7 @@ struct i40evf_adapter {
#define I40EVF_FLAG_CLIENT_NEEDS_L2_PARAMS BIT(17) #define I40EVF_FLAG_CLIENT_NEEDS_L2_PARAMS BIT(17)
#define I40EVF_FLAG_PROMISC_ON BIT(18) #define I40EVF_FLAG_PROMISC_ON BIT(18)
#define I40EVF_FLAG_ALLMULTI_ON BIT(19) #define I40EVF_FLAG_ALLMULTI_ON BIT(19)
#define I40EVF_FLAG_LEGACY_RX BIT(20)
/* duplicates for common code */ /* duplicates for common code */
#define I40E_FLAG_FDIR_ATR_ENABLED 0 #define I40E_FLAG_FDIR_ATR_ENABLED 0
#define I40E_FLAG_DCB_ENABLED 0 #define I40E_FLAG_DCB_ENABLED 0
...@@ -229,6 +230,7 @@ struct i40evf_adapter { ...@@ -229,6 +230,7 @@ struct i40evf_adapter {
#define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED #define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED
#define I40E_FLAG_WB_ON_ITR_CAPABLE I40EVF_FLAG_WB_ON_ITR_CAPABLE #define I40E_FLAG_WB_ON_ITR_CAPABLE I40EVF_FLAG_WB_ON_ITR_CAPABLE
#define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE #define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE
#define I40E_FLAG_LEGACY_RX I40EVF_FLAG_LEGACY_RX
/* flags for admin queue service task */ /* flags for admin queue service task */
u32 aq_required; u32 aq_required;
#define I40EVF_FLAG_AQ_ENABLE_QUEUES BIT(0) #define I40EVF_FLAG_AQ_ENABLE_QUEUES BIT(0)
......
...@@ -63,6 +63,29 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = { ...@@ -63,6 +63,29 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = {
#define I40EVF_STATS_LEN(_dev) \ #define I40EVF_STATS_LEN(_dev) \
(I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev)) (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
/* For now we have one and only one private flag and it is only defined
* when we have support for the SKIP_CPU_SYNC DMA attribute. Instead
* of leaving all this code sitting around empty we will strip it unless
* our one private flag is actually available.
*/
struct i40evf_priv_flags {
char flag_string[ETH_GSTRING_LEN];
u32 flag;
bool read_only;
};
#define I40EVF_PRIV_FLAG(_name, _flag, _read_only) { \
.flag_string = _name, \
.flag = _flag, \
.read_only = _read_only, \
}
static const struct i40evf_priv_flags i40evf_gstrings_priv_flags[] = {
I40EVF_PRIV_FLAG("legacy-rx", I40EVF_FLAG_LEGACY_RX, 0),
};
#define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_gstrings_priv_flags)
/** /**
* i40evf_get_link_ksettings - Get Link Speed and Duplex settings * i40evf_get_link_ksettings - Get Link Speed and Duplex settings
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -124,6 +147,8 @@ static int i40evf_get_sset_count(struct net_device *netdev, int sset) ...@@ -124,6 +147,8 @@ static int i40evf_get_sset_count(struct net_device *netdev, int sset)
{ {
if (sset == ETH_SS_STATS) if (sset == ETH_SS_STATS)
return I40EVF_STATS_LEN(netdev); return I40EVF_STATS_LEN(netdev);
else if (sset == ETH_SS_PRIV_FLAGS)
return I40EVF_PRIV_FLAGS_STR_LEN;
else else
return -EINVAL; return -EINVAL;
} }
...@@ -189,7 +214,83 @@ static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data) ...@@ -189,7 +214,83 @@ static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i); snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
} else if (sset == ETH_SS_PRIV_FLAGS) {
for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
snprintf(p, ETH_GSTRING_LEN, "%s",
i40evf_gstrings_priv_flags[i].flag_string);
p += ETH_GSTRING_LEN;
}
}
}
/**
* i40evf_get_priv_flags - report device private flags
* @dev: network interface device structure
*
* The get string set count and the string set should be matched for each
* flag returned. Add new strings for each flag to the i40e_gstrings_priv_flags
* array.
*
* Returns a u32 bitmap of flags.
**/
static u32 i40evf_get_priv_flags(struct net_device *netdev)
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
u32 i, ret_flags = 0;
for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
const struct i40evf_priv_flags *priv_flags;
priv_flags = &i40evf_gstrings_priv_flags[i];
if (priv_flags->flag & adapter->flags)
ret_flags |= BIT(i);
}
return ret_flags;
}
/**
* i40evf_set_priv_flags - set private flags
* @dev: network interface device structure
* @flags: bit flags to be set
**/
static int i40evf_set_priv_flags(struct net_device *netdev, u32 flags)
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
u64 changed_flags;
u32 i;
changed_flags = adapter->flags;
for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
const struct i40evf_priv_flags *priv_flags;
priv_flags = &i40evf_gstrings_priv_flags[i];
if (priv_flags->read_only)
continue;
if (flags & BIT(i))
adapter->flags |= priv_flags->flag;
else
adapter->flags &= ~(priv_flags->flag);
}
/* check for flags that changed */
changed_flags ^= adapter->flags;
/* Process any additional changes needed as a result of flag changes. */
/* issue a reset to force legacy-rx change to take effect */
if (changed_flags & I40EVF_FLAG_LEGACY_RX) {
if (netif_running(netdev)) {
adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
schedule_work(&adapter->reset_task);
}
} }
return 0;
} }
/** /**
...@@ -238,6 +339,7 @@ static void i40evf_get_drvinfo(struct net_device *netdev, ...@@ -238,6 +339,7 @@ static void i40evf_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->version, i40evf_driver_version, 32); strlcpy(drvinfo->version, i40evf_driver_version, 32);
strlcpy(drvinfo->fw_version, "N/A", 4); strlcpy(drvinfo->fw_version, "N/A", 4);
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN;
} }
/** /**
...@@ -649,6 +751,8 @@ static const struct ethtool_ops i40evf_ethtool_ops = { ...@@ -649,6 +751,8 @@ static const struct ethtool_ops i40evf_ethtool_ops = {
.get_strings = i40evf_get_strings, .get_strings = i40evf_get_strings,
.get_ethtool_stats = i40evf_get_ethtool_stats, .get_ethtool_stats = i40evf_get_ethtool_stats,
.get_sset_count = i40evf_get_sset_count, .get_sset_count = i40evf_get_sset_count,
.get_priv_flags = i40evf_get_priv_flags,
.set_priv_flags = i40evf_set_priv_flags,
.get_msglevel = i40evf_get_msglevel, .get_msglevel = i40evf_get_msglevel,
.set_msglevel = i40evf_set_msglevel, .set_msglevel = i40evf_set_msglevel,
.get_coalesce = i40evf_get_coalesce, .get_coalesce = i40evf_get_coalesce,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment