Commit 0da2b183 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2019-01-22

This series contains updates to i40e and xsk.

Jan exports xdp_get_umem_from_qid() for other drivers/modules to use.
Refactored the code use the netdev provided umems, instead of containing
them inside our i40e_vsi.

Aleksandr fixes an issue where RSS queues were misconfigured, so limit
the RSS queue number to the online CPU number.

Damian adds support for ethtool's setting and getting the FEC
configuration.

Grzegorz fixes a type mismatch, where the return value was not matching
the function declaration.

Sergey adds checks in the queue configuration handler to ensure the
number of queue pairs requested by the VF is less than maximum possible.

Lihong cleans up code left around from earlier silicon validation in the
i40e debugfs code.

Julia Lawall and Colin Ian King clean up white space indentation issues
found.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cc648f85 d1b3fa86
......@@ -34,6 +34,7 @@
#include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h>
#include <net/tc_act/tc_mirred.h>
#include <net/xdp_sock.h>
#include "i40e_type.h"
#include "i40e_prototype.h"
#include "i40e_client.h"
......@@ -523,6 +524,8 @@ struct i40e_pf {
#define I40E_FLAG_FD_SB_INACTIVE BIT(22)
#define I40E_FLAG_FD_SB_TO_CLOUD_FILTER BIT(23)
#define I40E_FLAG_DISABLE_FW_LLDP BIT(24)
#define I40E_FLAG_RS_FEC BIT(25)
#define I40E_FLAG_BASE_R_FEC BIT(26)
struct i40e_client_instance *cinst;
bool stat_offsets_loaded;
......@@ -787,11 +790,6 @@ struct i40e_vsi {
/* VSI specific handlers */
irqreturn_t (*irq_handler)(int irq, void *data);
/* AF_XDP zero-copy */
struct xdp_umem **xsk_umems;
u16 num_xsk_umems_used;
u16 num_xsk_umems;
} ____cacheline_internodealigned_in_smp;
struct i40e_netdev_priv {
......@@ -1091,6 +1089,8 @@ i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf);
i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf);
void i40e_print_link_message(struct i40e_vsi *vsi, bool isup);
void i40e_set_fec_in_flags(u8 fec_cfg, u32 *flags);
static inline bool i40e_enabled_xdp_vsi(struct i40e_vsi *vsi)
{
return !!vsi->xdp_prog;
......@@ -1104,10 +1104,10 @@ static inline struct xdp_umem *i40e_xsk_umem(struct i40e_ring *ring)
if (ring_is_xdp(ring))
qid -= ring->vsi->alloc_queue_pairs;
if (!ring->vsi->xsk_umems || !ring->vsi->xsk_umems[qid] || !xdp_on)
if (!xdp_on)
return NULL;
return ring->vsi->xsk_umems[qid];
return xdp_get_umem_from_qid(ring->vsi->netdev, qid);
}
int i40e_create_queue_channel(struct i40e_vsi *vsi, struct i40e_channel *ch);
......
......@@ -1642,30 +1642,7 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
count = buf_tmp - i40e_dbg_netdev_ops_buf + 1;
}
if (strncmp(i40e_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) {
cnt = sscanf(&i40e_dbg_netdev_ops_buf[11], "%i", &vsi_seid);
if (cnt != 1) {
dev_info(&pf->pdev->dev, "tx_timeout <vsi_seid>\n");
goto netdev_ops_write_done;
}
vsi = i40e_dbg_find_vsi(pf, vsi_seid);
if (!vsi) {
dev_info(&pf->pdev->dev,
"tx_timeout: VSI %d not found\n", vsi_seid);
} else if (!vsi->netdev) {
dev_info(&pf->pdev->dev, "tx_timeout: no netdev for VSI %d\n",
vsi_seid);
} else if (test_bit(__I40E_VSI_DOWN, vsi->state)) {
dev_info(&pf->pdev->dev, "tx_timeout: VSI %d not UP\n",
vsi_seid);
} else if (rtnl_trylock()) {
vsi->netdev->netdev_ops->ndo_tx_timeout(vsi->netdev);
rtnl_unlock();
dev_info(&pf->pdev->dev, "tx_timeout called\n");
} else {
dev_info(&pf->pdev->dev, "Could not acquire RTNL - please try again\n");
}
} else if (strncmp(i40e_dbg_netdev_ops_buf, "change_mtu", 10) == 0) {
if (strncmp(i40e_dbg_netdev_ops_buf, "change_mtu", 10) == 0) {
int mtu;
cnt = sscanf(&i40e_dbg_netdev_ops_buf[11], "%i %i",
......@@ -1733,7 +1710,6 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
dev_info(&pf->pdev->dev, "unknown command '%s'\n",
i40e_dbg_netdev_ops_buf);
dev_info(&pf->pdev->dev, "available commands\n");
dev_info(&pf->pdev->dev, " tx_timeout <vsi_seid>\n");
dev_info(&pf->pdev->dev, " change_mtu <vsi_seid> <mtu>\n");
dev_info(&pf->pdev->dev, " set_rx_mode <vsi_seid>\n");
dev_info(&pf->pdev->dev, " napi <vsi_seid>\n");
......
......@@ -438,6 +438,8 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
I40E_PRIV_FLAG("disable-source-pruning",
I40E_FLAG_SOURCE_PRUNING_DISABLED, 0),
I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_DISABLE_FW_LLDP, 0),
I40E_PRIV_FLAG("rs-fec", I40E_FLAG_RS_FEC, 0),
I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0),
};
#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
......@@ -606,6 +608,24 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf,
ethtool_link_ksettings_add_link_mode(ks, advertising,
25000baseCR_Full);
}
if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_AOC ||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_ACC) {
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB) {
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_BASER);
}
}
/* need to add new 10G PHY types */
if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU) {
......@@ -721,6 +741,13 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
25000baseSR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
25000baseSR_Full);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseSR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
......@@ -825,6 +852,9 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
40000baseKR4_Full);
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseKR_Full);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, supported,
20000baseKR2_Full);
ethtool_link_ksettings_add_link_mode(ks, supported,
......@@ -838,6 +868,10 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
40000baseKR4_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
25000baseKR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, advertising,
20000baseKR2_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
......@@ -855,6 +889,13 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
25000baseCR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
25000baseCR_Full);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_BASER);
break;
case I40E_PHY_TYPE_25GBASE_AOC:
case I40E_PHY_TYPE_25GBASE_ACC:
......@@ -862,9 +903,15 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseCR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
25000baseCR_Full);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE);
ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
ethtool_link_ksettings_add_link_mode(ks, advertising,
FEC_BASER);
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseCR_Full);
ethtool_link_ksettings_add_link_mode(ks, advertising,
......@@ -1261,6 +1308,154 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
return err;
}
static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_aq_get_phy_abilities_resp abilities;
struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw;
i40e_status status = 0;
u32 flags = 0;
int err = 0;
flags = READ_ONCE(pf->flags);
i40e_set_fec_in_flags(fec_cfg, &flags);
/* Get the current phy config */
memset(&abilities, 0, sizeof(abilities));
status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
NULL);
if (status) {
err = -EAGAIN;
goto done;
}
if (abilities.fec_cfg_curr_mod_ext_info != fec_cfg) {
struct i40e_aq_set_phy_config config;
memset(&config, 0, sizeof(config));
config.phy_type = abilities.phy_type;
config.abilities = abilities.abilities;
config.phy_type_ext = abilities.phy_type_ext;
config.link_speed = abilities.link_speed;
config.eee_capability = abilities.eee_capability;
config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan;
config.fec_config = fec_cfg & I40E_AQ_PHY_FEC_CONFIG_MASK;
status = i40e_aq_set_phy_config(hw, &config, NULL);
if (status) {
netdev_info(netdev,
"Set phy config failed, err %s aq_err %s\n",
i40e_stat_str(hw, status),
i40e_aq_str(hw, hw->aq.asq_last_status));
err = -EAGAIN;
goto done;
}
pf->flags = flags;
status = i40e_update_link_info(hw);
if (status)
/* debug level message only due to relation to the link
* itself rather than to the FEC settings
* (e.g. no physical connection etc.)
*/
netdev_dbg(netdev,
"Updating link info failed with err %s aq_err %s\n",
i40e_stat_str(hw, status),
i40e_aq_str(hw, hw->aq.asq_last_status));
}
done:
return err;
}
static int i40e_get_fec_param(struct net_device *netdev,
struct ethtool_fecparam *fecparam)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_aq_get_phy_abilities_resp abilities;
struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw;
i40e_status status = 0;
int err = 0;
/* Get the current phy config */
memset(&abilities, 0, sizeof(abilities));
status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
NULL);
if (status) {
err = -EAGAIN;
goto done;
}
fecparam->fec = 0;
if (abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_AUTO)
fecparam->fec |= ETHTOOL_FEC_AUTO;
if ((abilities.fec_cfg_curr_mod_ext_info &
I40E_AQ_SET_FEC_REQUEST_RS) ||
(abilities.fec_cfg_curr_mod_ext_info &
I40E_AQ_SET_FEC_ABILITY_RS))
fecparam->fec |= ETHTOOL_FEC_RS;
if ((abilities.fec_cfg_curr_mod_ext_info &
I40E_AQ_SET_FEC_REQUEST_KR) ||
(abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_ABILITY_KR))
fecparam->fec |= ETHTOOL_FEC_BASER;
if (abilities.fec_cfg_curr_mod_ext_info == 0)
fecparam->fec |= ETHTOOL_FEC_OFF;
if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_KR_ENA)
fecparam->active_fec = ETHTOOL_FEC_BASER;
else if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_RS_ENA)
fecparam->active_fec = ETHTOOL_FEC_RS;
else
fecparam->active_fec = ETHTOOL_FEC_OFF;
done:
return err;
}
static int i40e_set_fec_param(struct net_device *netdev,
struct ethtool_fecparam *fecparam)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
struct i40e_hw *hw = &pf->hw;
u8 fec_cfg = 0;
int err = 0;
if (hw->device_id != I40E_DEV_ID_25G_SFP28 &&
hw->device_id != I40E_DEV_ID_25G_B) {
err = -EPERM;
goto done;
}
switch (fecparam->fec) {
case ETHTOOL_FEC_AUTO:
fec_cfg = I40E_AQ_SET_FEC_AUTO;
break;
case ETHTOOL_FEC_RS:
fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
I40E_AQ_SET_FEC_ABILITY_RS);
break;
case ETHTOOL_FEC_BASER:
fec_cfg = (I40E_AQ_SET_FEC_REQUEST_KR |
I40E_AQ_SET_FEC_ABILITY_KR);
break;
case ETHTOOL_FEC_OFF:
case ETHTOOL_FEC_NONE:
fec_cfg = 0;
break;
default:
dev_warn(&pf->pdev->dev, "Unsupported FEC mode: %d",
fecparam->fec);
err = -EINVAL;
goto done;
}
err = i40e_set_fec_cfg(netdev, fec_cfg);
done:
return err;
}
static int i40e_nway_reset(struct net_device *netdev)
{
/* restart autonegotiation */
......@@ -2175,7 +2370,7 @@ static int i40e_get_ts_info(struct net_device *dev,
return 0;
}
static int i40e_link_test(struct net_device *netdev, u64 *data)
static u64 i40e_link_test(struct net_device *netdev, u64 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
......@@ -2198,7 +2393,7 @@ static int i40e_link_test(struct net_device *netdev, u64 *data)
return *data;
}
static int i40e_reg_test(struct net_device *netdev, u64 *data)
static u64 i40e_reg_test(struct net_device *netdev, u64 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
......@@ -2209,7 +2404,7 @@ static int i40e_reg_test(struct net_device *netdev, u64 *data)
return *data;
}
static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
static u64 i40e_eeprom_test(struct net_device *netdev, u64 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
......@@ -2223,7 +2418,7 @@ static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
return *data;
}
static int i40e_intr_test(struct net_device *netdev, u64 *data)
static u64 i40e_intr_test(struct net_device *netdev, u64 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
......@@ -4676,6 +4871,15 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
}
}
if (((changed_flags & I40E_FLAG_RS_FEC) ||
(changed_flags & I40E_FLAG_BASE_R_FEC)) &&
pf->hw.device_id != I40E_DEV_ID_25G_SFP28 &&
pf->hw.device_id != I40E_DEV_ID_25G_B) {
dev_warn(&pf->pdev->dev,
"Device does not support changing FEC configuration\n");
return -EOPNOTSUPP;
}
/* Now that we've checked to ensure that the new flags are valid, load
* them into place. Since we only modify flags either (a) during
* initialization or (b) while holding the RTNL lock, we don't need
......@@ -4714,6 +4918,24 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
}
}
if ((changed_flags & I40E_FLAG_RS_FEC) ||
(changed_flags & I40E_FLAG_BASE_R_FEC)) {
u8 fec_cfg = 0;
if (pf->flags & I40E_FLAG_RS_FEC &&
pf->flags & I40E_FLAG_BASE_R_FEC) {
fec_cfg = I40E_AQ_SET_FEC_AUTO;
} else if (pf->flags & I40E_FLAG_RS_FEC) {
fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
I40E_AQ_SET_FEC_ABILITY_RS);
} else if (pf->flags & I40E_FLAG_BASE_R_FEC) {
fec_cfg = (I40E_AQ_SET_FEC_REQUEST_KR |
I40E_AQ_SET_FEC_ABILITY_KR);
}
if (i40e_set_fec_cfg(dev, fec_cfg))
dev_warn(&pf->pdev->dev, "Cannot change FEC config\n");
}
if ((changed_flags & pf->flags &
I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
(pf->flags & I40E_FLAG_MFP_ENABLED))
......@@ -4948,6 +5170,8 @@ static const struct ethtool_ops i40e_ethtool_ops = {
.set_per_queue_coalesce = i40e_set_per_queue_coalesce,
.get_link_ksettings = i40e_get_link_ksettings,
.set_link_ksettings = i40e_set_link_ksettings,
.get_fecparam = i40e_get_fec_param,
.set_fecparam = i40e_set_fec_param,
};
void i40e_set_ethtool_ops(struct net_device *netdev)
......
......@@ -26,8 +26,8 @@ static const char i40e_driver_string[] =
#define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 2
#define DRV_VERSION_MINOR 7
#define DRV_VERSION_BUILD 6
#define DRV_VERSION_MINOR 8
#define DRV_VERSION_BUILD 10
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
......@@ -11042,6 +11042,7 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
if (!(pf->flags & I40E_FLAG_RSS_ENABLED))
return 0;
queue_count = min_t(int, queue_count, num_online_cpus());
new_rss_size = min_t(int, queue_count, pf->rss_size_max);
if (queue_count != vsi->num_queue_pairs) {
......@@ -13859,6 +13860,29 @@ static void i40e_get_platform_mac_addr(struct pci_dev *pdev, struct i40e_pf *pf)
i40e_get_mac_addr(&pf->hw, pf->hw.mac.addr);
}
/**
* i40e_set_fec_in_flags - helper function for setting FEC options in flags
* @fec_cfg: FEC option to set in flags
* @flags: ptr to flags in which we set FEC option
**/
void i40e_set_fec_in_flags(u8 fec_cfg, u32 *flags)
{
if (fec_cfg & I40E_AQ_SET_FEC_AUTO)
*flags |= I40E_FLAG_RS_FEC | I40E_FLAG_BASE_R_FEC;
if ((fec_cfg & I40E_AQ_SET_FEC_REQUEST_RS) ||
(fec_cfg & I40E_AQ_SET_FEC_ABILITY_RS)) {
*flags |= I40E_FLAG_RS_FEC;
*flags &= ~I40E_FLAG_BASE_R_FEC;
}
if ((fec_cfg & I40E_AQ_SET_FEC_REQUEST_KR) ||
(fec_cfg & I40E_AQ_SET_FEC_ABILITY_KR)) {
*flags |= I40E_FLAG_BASE_R_FEC;
*flags &= ~I40E_FLAG_RS_FEC;
}
if (fec_cfg == 0)
*flags &= ~(I40E_FLAG_RS_FEC | I40E_FLAG_BASE_R_FEC);
}
/**
* i40e_probe - Device initialization routine
* @pdev: PCI device information struct
......@@ -14350,6 +14374,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
pf->hw.phy.link_info.requested_speeds = abilities.link_speed;
/* set the FEC config due to the board capabilities */
i40e_set_fec_in_flags(abilities.fec_cfg_curr_mod_ext_info, &pf->flags);
/* get the supported phy types from the fw */
err = i40e_aq_get_phy_capabilities(hw, false, true, &abilities, NULL);
if (err)
......
......@@ -2069,6 +2069,11 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
goto error_param;
}
if (qci->num_queue_pairs > I40E_MAX_VF_QUEUES) {
aq_ret = I40E_ERR_PARAM;
goto error_param;
}
for (i = 0; i < qci->num_queue_pairs; i++) {
qpi = &qci->qpair[i];
......@@ -3656,7 +3661,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
int ret;
pf->vf_aq_requests++;
if (local_vf_id >= pf->num_alloc_vfs)
if (local_vf_id < 0 || local_vf_id >= pf->num_alloc_vfs)
return -EINVAL;
vf = &(pf->vf[local_vf_id]);
......
......@@ -9,69 +9,6 @@
#include "i40e_txrx_common.h"
#include "i40e_xsk.h"
/**
* i40e_alloc_xsk_umems - Allocate an array to store per ring UMEMs
* @vsi: Current VSI
*
* Returns 0 on success, <0 on failure
**/
static int i40e_alloc_xsk_umems(struct i40e_vsi *vsi)
{
if (vsi->xsk_umems)
return 0;
vsi->num_xsk_umems_used = 0;
vsi->num_xsk_umems = vsi->alloc_queue_pairs;
vsi->xsk_umems = kcalloc(vsi->num_xsk_umems, sizeof(*vsi->xsk_umems),
GFP_KERNEL);
if (!vsi->xsk_umems) {
vsi->num_xsk_umems = 0;
return -ENOMEM;
}
return 0;
}
/**
* i40e_add_xsk_umem - Store a UMEM for a certain ring/qid
* @vsi: Current VSI
* @umem: UMEM to store
* @qid: Ring/qid to associate with the UMEM
*
* Returns 0 on success, <0 on failure
**/
static int i40e_add_xsk_umem(struct i40e_vsi *vsi, struct xdp_umem *umem,
u16 qid)
{
int err;
err = i40e_alloc_xsk_umems(vsi);
if (err)
return err;
vsi->xsk_umems[qid] = umem;
vsi->num_xsk_umems_used++;
return 0;
}
/**
* i40e_remove_xsk_umem - Remove a UMEM for a certain ring/qid
* @vsi: Current VSI
* @qid: Ring/qid associated with the UMEM
**/
static void i40e_remove_xsk_umem(struct i40e_vsi *vsi, u16 qid)
{
vsi->xsk_umems[qid] = NULL;
vsi->num_xsk_umems_used--;
if (vsi->num_xsk_umems == 0) {
kfree(vsi->xsk_umems);
vsi->xsk_umems = NULL;
vsi->num_xsk_umems = 0;
}
}
/**
* i40e_xsk_umem_dma_map - DMA maps all UMEM memory for the netdev
* @vsi: Current VSI
......@@ -140,6 +77,7 @@ static void i40e_xsk_umem_dma_unmap(struct i40e_vsi *vsi, struct xdp_umem *umem)
static int i40e_xsk_umem_enable(struct i40e_vsi *vsi, struct xdp_umem *umem,
u16 qid)
{
struct net_device *netdev = vsi->netdev;
struct xdp_umem_fq_reuse *reuseq;
bool if_running;
int err;
......@@ -150,12 +88,9 @@ static int i40e_xsk_umem_enable(struct i40e_vsi *vsi, struct xdp_umem *umem,
if (qid >= vsi->num_queue_pairs)
return -EINVAL;
if (vsi->xsk_umems) {
if (qid >= vsi->num_xsk_umems)
if (qid >= netdev->real_num_rx_queues ||
qid >= netdev->real_num_tx_queues)
return -EINVAL;
if (vsi->xsk_umems[qid])
return -EBUSY;
}
reuseq = xsk_reuseq_prepare(vsi->rx_rings[0]->count);
if (!reuseq)
......@@ -173,13 +108,7 @@ static int i40e_xsk_umem_enable(struct i40e_vsi *vsi, struct xdp_umem *umem,
err = i40e_queue_pair_disable(vsi, qid);
if (err)
return err;
}
err = i40e_add_xsk_umem(vsi, umem, qid);
if (err)
return err;
if (if_running) {
err = i40e_queue_pair_enable(vsi, qid);
if (err)
return err;
......@@ -197,11 +126,13 @@ static int i40e_xsk_umem_enable(struct i40e_vsi *vsi, struct xdp_umem *umem,
**/
static int i40e_xsk_umem_disable(struct i40e_vsi *vsi, u16 qid)
{
struct net_device *netdev = vsi->netdev;
struct xdp_umem *umem;
bool if_running;
int err;
if (!vsi->xsk_umems || qid >= vsi->num_xsk_umems ||
!vsi->xsk_umems[qid])
umem = xdp_get_umem_from_qid(netdev, qid);
if (!umem)
return -EINVAL;
if_running = netif_running(vsi->netdev) && i40e_enabled_xdp_vsi(vsi);
......@@ -212,8 +143,7 @@ static int i40e_xsk_umem_disable(struct i40e_vsi *vsi, u16 qid)
return err;
}
i40e_xsk_umem_dma_unmap(vsi, vsi->xsk_umems[qid]);
i40e_remove_xsk_umem(vsi, qid);
i40e_xsk_umem_dma_unmap(vsi, umem);
if (if_running) {
err = i40e_queue_pair_enable(vsi, qid);
......@@ -237,20 +167,18 @@ static int i40e_xsk_umem_disable(struct i40e_vsi *vsi, u16 qid)
int i40e_xsk_umem_query(struct i40e_vsi *vsi, struct xdp_umem **umem,
u16 qid)
{
struct net_device *netdev = vsi->netdev;
struct xdp_umem *queried_umem;
if (vsi->type != I40E_VSI_MAIN)
return -EINVAL;
if (qid >= vsi->num_queue_pairs)
return -EINVAL;
queried_umem = xdp_get_umem_from_qid(netdev, qid);
if (vsi->xsk_umems) {
if (qid >= vsi->num_xsk_umems)
if (!queried_umem)
return -EINVAL;
*umem = vsi->xsk_umems[qid];
return 0;
}
*umem = NULL;
*umem = queried_umem;
return 0;
}
......@@ -945,13 +873,11 @@ void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring)
**/
bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi)
{
struct net_device *netdev = vsi->netdev;
int i;
if (!vsi->xsk_umems)
return false;
for (i = 0; i < vsi->num_queue_pairs; i++) {
if (vsi->xsk_umems[i])
if (xdp_get_umem_from_qid(netdev, i))
return true;
}
......
......@@ -67,6 +67,7 @@ struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
return NULL;
}
EXPORT_SYMBOL(xdp_get_umem_from_qid);
static void xdp_clear_umem_at_qid(struct net_device *dev, u16 queue_id)
{
......
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