Commit 00cc3679 authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-11-25

This series contains updates to fm10k, i40e and i40evf.

Alex Duyck fixes up fm10k to use napi_schedule_irqoff() instead of
napi_schedule() since the function it is called from runs from hard interrupt
context or with interrupts already disabled in netpoll.

Shannon cleans up i40e and i40evf unused cd_tunneling parameter and any code
comments that refer to it.  Then clean up a few instances of BUG_ON, based
on a Linux diatribe, especially when WARN_ON can be used.

Helin fixed a issue where using ethtool RXNFC command could let receive
flow hash could be set on disabled queues, so resolve by returning the
number of enabled queues before setting RXNFC.

Anjali fixes a MSS issue where the hardware/NVM sets a limit of no less than
256 bytes for MSS, yet the stack can send as low as 76 byte MSS.  Fixed the
issue by lowering the hardware limit to 64 bytes to avoid MDDs from firing
and causing a reset when the MSS is lower than 256.  Added a statistic to
track how many times we forced to do a write back on transmit if the
number of descriptors pending are less than a cache line.

Catherine fixes link status changes, where polling would only change link
status changes in one direction depending on what the last old data saved
off was.  This was due to the watchdog only calling link_event and not
handle_link_event.

Mitch cleans up and enhances error messages related to VF MAC/VLAN filters.

v2: Dropped patch "i40e: Properly cast type for arithmetic" patch
    based on feedback from the community
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9458ceab 1c2df9e5
...@@ -846,7 +846,7 @@ static irqreturn_t fm10k_msix_clean_rings(int __always_unused irq, void *data) ...@@ -846,7 +846,7 @@ static irqreturn_t fm10k_msix_clean_rings(int __always_unused irq, void *data)
struct fm10k_q_vector *q_vector = data; struct fm10k_q_vector *q_vector = data;
if (q_vector->rx.count || q_vector->tx.count) if (q_vector->rx.count || q_vector->tx.count)
napi_schedule(&q_vector->napi); napi_schedule_irqoff(&q_vector->napi);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -187,6 +187,7 @@ struct i40e_lump_tracking { ...@@ -187,6 +187,7 @@ struct i40e_lump_tracking {
#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4) #define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
#define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4) #define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4)
#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
enum i40e_fd_stat_idx { enum i40e_fd_stat_idx {
I40E_FD_STAT_ATR, I40E_FD_STAT_ATR,
...@@ -487,6 +488,7 @@ struct i40e_vsi { ...@@ -487,6 +488,7 @@ struct i40e_vsi {
u32 tx_restart; u32 tx_restart;
u32 tx_busy; u32 tx_busy;
u64 tx_linearize; u64 tx_linearize;
u64 tx_force_wb;
u32 rx_buf_failed; u32 rx_buf_failed;
u32 rx_page_failed; u32 rx_page_failed;
...@@ -668,6 +670,8 @@ extern const char i40e_driver_name[]; ...@@ -668,6 +670,8 @@ extern const char i40e_driver_name[];
extern const char i40e_driver_version_str[]; extern const char i40e_driver_version_str[];
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags); void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags); void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id); struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
void i40e_update_stats(struct i40e_vsi *vsi); void i40e_update_stats(struct i40e_vsi *vsi);
void i40e_update_eth_stats(struct i40e_vsi *vsi); void i40e_update_eth_stats(struct i40e_vsi *vsi);
......
...@@ -2403,4 +2403,4 @@ struct i40e_aqc_debug_modify_internals { ...@@ -2403,4 +2403,4 @@ struct i40e_aqc_debug_modify_internals {
I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals); I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals);
#endif #endif /* _I40E_ADMINQ_CMD_H_ */
...@@ -88,6 +88,7 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = { ...@@ -88,6 +88,7 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = {
I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast), I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol), I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
I40E_VSI_STAT("tx_linearize", tx_linearize), I40E_VSI_STAT("tx_linearize", tx_linearize),
I40E_VSI_STAT("tx_force_wb", tx_force_wb),
}; };
/* These PF_STATs might look like duplicates of some NETDEV_STATs, /* These PF_STATs might look like duplicates of some NETDEV_STATs,
...@@ -2110,7 +2111,7 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, ...@@ -2110,7 +2111,7 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
switch (cmd->cmd) { switch (cmd->cmd) {
case ETHTOOL_GRXRINGS: case ETHTOOL_GRXRINGS:
cmd->data = vsi->alloc_queue_pairs; cmd->data = vsi->num_queue_pairs;
ret = 0; ret = 0;
break; break;
case ETHTOOL_GRXFH: case ETHTOOL_GRXFH:
...@@ -2583,7 +2584,6 @@ static int i40e_set_channels(struct net_device *dev, ...@@ -2583,7 +2584,6 @@ static int i40e_set_channels(struct net_device *dev,
return -EINVAL; return -EINVAL;
} }
#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
/** /**
* i40e_get_rxfh_key_size - get the RSS hash key size * i40e_get_rxfh_key_size - get the RSS hash key size
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -2611,10 +2611,9 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -2611,10 +2611,9 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
{ {
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back; u8 *lut, *seed = NULL;
struct i40e_hw *hw = &pf->hw; int ret;
u32 reg_val; u16 i;
int i, j;
if (hfunc) if (hfunc)
*hfunc = ETH_RSS_HASH_TOP; *hfunc = ETH_RSS_HASH_TOP;
...@@ -2622,24 +2621,20 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -2622,24 +2621,20 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
if (!indir) if (!indir)
return 0; return 0;
for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) { seed = key;
reg_val = rd32(hw, I40E_PFQF_HLUT(i)); lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
indir[j++] = reg_val & 0xff; if (!lut)
indir[j++] = (reg_val >> 8) & 0xff; return -ENOMEM;
indir[j++] = (reg_val >> 16) & 0xff; ret = i40e_get_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
indir[j++] = (reg_val >> 24) & 0xff; if (ret)
} goto out;
for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
indir[i] = (u32)(lut[i]);
if (key) { out:
for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { kfree(lut);
reg_val = rd32(hw, I40E_PFQF_HKEY(i));
key[j++] = (u8)(reg_val & 0xff); return ret;
key[j++] = (u8)((reg_val >> 8) & 0xff);
key[j++] = (u8)((reg_val >> 16) & 0xff);
key[j++] = (u8)((reg_val >> 24) & 0xff);
}
}
return 0;
} }
/** /**
...@@ -2656,10 +2651,10 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -2656,10 +2651,10 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
{ {
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi; struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back; u8 seed_def[I40E_HKEY_ARRAY_SIZE];
struct i40e_hw *hw = &pf->hw; u8 *lut, *seed = NULL;
u32 reg_val; u16 i;
int i, j; int ret;
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -2667,24 +2662,19 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -2667,24 +2662,19 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
if (!indir) if (!indir)
return 0; return 0;
for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
reg_val = indir[j++];
reg_val |= indir[j++] << 8;
reg_val |= indir[j++] << 16;
reg_val |= indir[j++] << 24;
wr32(hw, I40E_PFQF_HLUT(i), reg_val);
}
if (key) { if (key) {
for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { memcpy(seed_def, key, I40E_HKEY_ARRAY_SIZE);
reg_val = key[j++]; seed = seed_def;
reg_val |= key[j++] << 8;
reg_val |= key[j++] << 16;
reg_val |= key[j++] << 24;
wr32(hw, I40E_PFQF_HKEY(i), reg_val);
}
} }
return 0; lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
if (!lut)
return -ENOMEM;
for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
lut[i] = (u8)(indir[i]);
ret = i40e_config_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
kfree(lut);
return ret;
} }
/** /**
......
...@@ -1544,8 +1544,6 @@ void i40e_fcoe_vsi_setup(struct i40e_pf *pf) ...@@ -1544,8 +1544,6 @@ void i40e_fcoe_vsi_setup(struct i40e_pf *pf)
if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) if (!(pf->flags & I40E_FLAG_FCOE_ENABLED))
return; return;
BUG_ON(!pf->vsi[pf->lan_vsi]);
for (i = 0; i < pf->num_alloc_vsi; i++) { for (i = 0; i < pf->num_alloc_vsi; i++) {
vsi = pf->vsi[i]; vsi = pf->vsi[i];
if (vsi && vsi->type == I40E_VSI_FCOE) { if (vsi && vsi->type == I40E_VSI_FCOE) {
......
...@@ -38,8 +38,8 @@ static const char i40e_driver_string[] = ...@@ -38,8 +38,8 @@ static const char i40e_driver_string[] =
#define DRV_KERN "-k" #define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 3 #define DRV_VERSION_MINOR 4
#define DRV_VERSION_BUILD 46 #define DRV_VERSION_BUILD 2
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN __stringify(DRV_VERSION_BUILD) DRV_KERN
...@@ -55,6 +55,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit); ...@@ -55,6 +55,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit);
static int i40e_setup_misc_vector(struct i40e_pf *pf); static int i40e_setup_misc_vector(struct i40e_pf *pf);
static void i40e_determine_queue_usage(struct i40e_pf *pf); static void i40e_determine_queue_usage(struct i40e_pf *pf);
static int i40e_setup_pf_filter_control(struct i40e_pf *pf); static int i40e_setup_pf_filter_control(struct i40e_pf *pf);
static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
u16 rss_table_size, u16 rss_size);
static void i40e_fdir_sb_setup(struct i40e_pf *pf); static void i40e_fdir_sb_setup(struct i40e_pf *pf);
static int i40e_veb_get_bw_info(struct i40e_veb *veb); static int i40e_veb_get_bw_info(struct i40e_veb *veb);
...@@ -881,6 +883,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) ...@@ -881,6 +883,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
u64 bytes, packets; u64 bytes, packets;
unsigned int start; unsigned int start;
u64 tx_linearize; u64 tx_linearize;
u64 tx_force_wb;
u64 rx_p, rx_b; u64 rx_p, rx_b;
u64 tx_p, tx_b; u64 tx_p, tx_b;
u16 q; u16 q;
...@@ -899,7 +902,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) ...@@ -899,7 +902,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
*/ */
rx_b = rx_p = 0; rx_b = rx_p = 0;
tx_b = tx_p = 0; tx_b = tx_p = 0;
tx_restart = tx_busy = tx_linearize = 0; tx_restart = tx_busy = tx_linearize = tx_force_wb = 0;
rx_page = 0; rx_page = 0;
rx_buf = 0; rx_buf = 0;
rcu_read_lock(); rcu_read_lock();
...@@ -917,6 +920,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) ...@@ -917,6 +920,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
tx_restart += p->tx_stats.restart_queue; tx_restart += p->tx_stats.restart_queue;
tx_busy += p->tx_stats.tx_busy; tx_busy += p->tx_stats.tx_busy;
tx_linearize += p->tx_stats.tx_linearize; tx_linearize += p->tx_stats.tx_linearize;
tx_force_wb += p->tx_stats.tx_force_wb;
/* Rx queue is part of the same block as Tx queue */ /* Rx queue is part of the same block as Tx queue */
p = &p[1]; p = &p[1];
...@@ -934,6 +938,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) ...@@ -934,6 +938,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
vsi->tx_restart = tx_restart; vsi->tx_restart = tx_restart;
vsi->tx_busy = tx_busy; vsi->tx_busy = tx_busy;
vsi->tx_linearize = tx_linearize; vsi->tx_linearize = tx_linearize;
vsi->tx_force_wb = tx_force_wb;
vsi->rx_page_failed = rx_page; vsi->rx_page_failed = rx_page;
vsi->rx_buf_failed = rx_buf; vsi->rx_buf_failed = rx_buf;
...@@ -5738,7 +5743,7 @@ static void i40e_handle_lan_overflow_event(struct i40e_pf *pf, ...@@ -5738,7 +5743,7 @@ static void i40e_handle_lan_overflow_event(struct i40e_pf *pf,
**/ **/
static void i40e_service_event_complete(struct i40e_pf *pf) static void i40e_service_event_complete(struct i40e_pf *pf)
{ {
BUG_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state)); WARN_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state));
/* flush memory to make sure state is correct before next watchog */ /* flush memory to make sure state is correct before next watchog */
smp_mb__before_atomic(); smp_mb__before_atomic();
...@@ -6013,6 +6018,9 @@ static void i40e_link_event(struct i40e_pf *pf) ...@@ -6013,6 +6018,9 @@ static void i40e_link_event(struct i40e_pf *pf)
i40e_status status; i40e_status status;
bool new_link, old_link; bool new_link, old_link;
/* save off old link status information */
pf->hw.phy.link_info_old = pf->hw.phy.link_info;
/* set this to force the get_link_status call to refresh state */ /* set this to force the get_link_status call to refresh state */
pf->hw.phy.get_link_info = true; pf->hw.phy.get_link_info = true;
...@@ -6147,13 +6155,9 @@ static void i40e_reset_subtask(struct i40e_pf *pf) ...@@ -6147,13 +6155,9 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
static void i40e_handle_link_event(struct i40e_pf *pf, static void i40e_handle_link_event(struct i40e_pf *pf,
struct i40e_arq_event_info *e) struct i40e_arq_event_info *e)
{ {
struct i40e_hw *hw = &pf->hw;
struct i40e_aqc_get_link_status *status = struct i40e_aqc_get_link_status *status =
(struct i40e_aqc_get_link_status *)&e->desc.params.raw; (struct i40e_aqc_get_link_status *)&e->desc.params.raw;
/* save off old link status information */
hw->phy.link_info_old = hw->phy.link_info;
/* Do a new status request to re-enable LSE reporting /* Do a new status request to re-enable LSE reporting
* and load new status information into the hw struct * and load new status information into the hw struct
* This completely ignores any state information * This completely ignores any state information
...@@ -6685,6 +6689,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) ...@@ -6685,6 +6689,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
u8 set_fc_aq_fail = 0; u8 set_fc_aq_fail = 0;
i40e_status ret; i40e_status ret;
u32 val;
u32 v; u32 v;
/* Now we wait for GRST to settle out. /* Now we wait for GRST to settle out.
...@@ -6823,6 +6828,20 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) ...@@ -6823,6 +6828,20 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
} }
} }
/* Reconfigure hardware for allowing smaller MSS in the case
* of TSO, so that we avoid the MDD being fired and causing
* a reset in the case of small MSS+TSO.
*/
#define I40E_REG_MSS 0x000E64DC
#define I40E_REG_MSS_MIN_MASK 0x3FF0000
#define I40E_64BYTE_MSS 0x400000
val = rd32(hw, I40E_REG_MSS);
if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
val &= ~I40E_REG_MSS_MIN_MASK;
val |= I40E_64BYTE_MSS;
wr32(hw, I40E_REG_MSS, val);
}
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) || if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
(pf->hw.aq.fw_maj_ver < 4)) { (pf->hw.aq.fw_maj_ver < 4)) {
msleep(75); msleep(75);
...@@ -7780,7 +7799,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) ...@@ -7780,7 +7799,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
* @vsi: vsi structure * @vsi: vsi structure
* @seed: RSS hash seed * @seed: RSS hash seed
**/ **/
static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed) static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
u8 *lut, u16 lut_size)
{ {
struct i40e_aqc_get_set_rss_key_data rss_key; struct i40e_aqc_get_set_rss_key_data rss_key;
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
...@@ -7833,43 +7853,57 @@ static int i40e_vsi_config_rss(struct i40e_vsi *vsi) ...@@ -7833,43 +7853,57 @@ static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
{ {
u8 seed[I40E_HKEY_ARRAY_SIZE]; u8 seed[I40E_HKEY_ARRAY_SIZE];
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
u8 *lut;
int ret;
if (!(pf->flags & I40E_FLAG_RSS_AQ_CAPABLE))
return 0;
lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
if (!lut)
return -ENOMEM;
i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE); netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs); vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs);
ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
kfree(lut);
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) return ret;
return i40e_config_rss_aq(vsi, seed);
return 0;
} }
/** /**
* i40e_config_rss_reg - Prepare for RSS if used * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
* @pf: board private structure * @vsi: Pointer to vsi structure
* @seed: RSS hash seed * @seed: RSS hash seed
* @lut: Lookup table
* @lut_size: Lookup table size
*
* Returns 0 on success, negative on failure
**/ **/
static int i40e_config_rss_reg(struct i40e_pf *pf, const u8 *seed) static int i40e_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
const u8 *lut, u16 lut_size)
{ {
struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
u32 *seed_dw = (u32 *)seed; u8 i;
u32 current_queue = 0;
u32 lut = 0;
int i, j;
/* Fill out hash function seed */ /* Fill out hash function seed */
for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) if (seed) {
wr32(hw, I40E_PFQF_HKEY(i), seed_dw[i]); u32 *seed_dw = (u32 *)seed;
for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) { for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
lut = 0; wr32(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
for (j = 0; j < 4; j++) { }
if (current_queue == vsi->rss_size)
current_queue = 0; if (lut) {
lut |= ((current_queue) << (8 * j)); u32 *lut_dw = (u32 *)lut;
current_queue++;
} if (lut_size != I40E_HLUT_ARRAY_SIZE)
wr32(&pf->hw, I40E_PFQF_HLUT(i), lut); return -EINVAL;
for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
wr32(hw, I40E_PFQF_HLUT(i), lut_dw[i]);
} }
i40e_flush(hw); i40e_flush(hw);
...@@ -7877,18 +7911,101 @@ static int i40e_config_rss_reg(struct i40e_pf *pf, const u8 *seed) ...@@ -7877,18 +7911,101 @@ static int i40e_config_rss_reg(struct i40e_pf *pf, const u8 *seed)
} }
/** /**
* i40e_config_rss - Prepare for RSS if used * i40e_get_rss_reg - Get the RSS keys and lut by reading registers
* @vsi: Pointer to VSI structure
* @seed: Buffer to store the keys
* @lut: Buffer to store the lookup table entries
* @lut_size: Size of buffer to store the lookup table entries
*
* Returns 0 on success, negative on failure
*/
static int i40e_get_rss_reg(struct i40e_vsi *vsi, u8 *seed,
u8 *lut, u16 lut_size)
{
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
u16 i;
if (seed) {
u32 *seed_dw = (u32 *)seed;
for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
seed_dw[i] = rd32(hw, I40E_PFQF_HKEY(i));
}
if (lut) {
u32 *lut_dw = (u32 *)lut;
if (lut_size != I40E_HLUT_ARRAY_SIZE)
return -EINVAL;
for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
lut_dw[i] = rd32(hw, I40E_PFQF_HLUT(i));
}
return 0;
}
/**
* i40e_config_rss - Configure RSS keys and lut
* @vsi: Pointer to VSI structure
* @seed: RSS hash seed
* @lut: Lookup table
* @lut_size: Lookup table size
*
* Returns 0 on success, negative on failure
*/
int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
{
struct i40e_pf *pf = vsi->back;
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
return i40e_config_rss_aq(vsi, seed, lut, lut_size);
else
return i40e_config_rss_reg(vsi, seed, lut, lut_size);
}
/**
* i40e_get_rss - Get RSS keys and lut
* @vsi: Pointer to VSI structure
* @seed: Buffer to store the keys
* @lut: Buffer to store the lookup table entries
* lut_size: Size of buffer to store the lookup table entries
*
* Returns 0 on success, negative on failure
*/
int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
{
return i40e_get_rss_reg(vsi, seed, lut, lut_size);
}
/**
* i40e_fill_rss_lut - Fill the RSS lookup table with default values
* @pf: Pointer to board private structure
* @lut: Lookup table
* @rss_table_size: Lookup table size
* @rss_size: Range of queue number for hashing
*/
static void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
u16 rss_table_size, u16 rss_size)
{
u16 i;
for (i = 0; i < rss_table_size; i++)
lut[i] = i % rss_size;
}
/**
* i40e_pf_config_rss - Prepare for RSS if used
* @pf: board private structure * @pf: board private structure
**/ **/
static int i40e_config_rss(struct i40e_pf *pf) static int i40e_pf_config_rss(struct i40e_pf *pf)
{ {
struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
u8 seed[I40E_HKEY_ARRAY_SIZE]; u8 seed[I40E_HKEY_ARRAY_SIZE];
u8 *lut;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
u32 reg_val; u32 reg_val;
u64 hena; u64 hena;
int ret;
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
/* By default we enable TCP/UDP with IPv4/IPv6 ptypes */ /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */
hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) | hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
...@@ -7907,10 +8024,18 @@ static int i40e_config_rss(struct i40e_pf *pf) ...@@ -7907,10 +8024,18 @@ static int i40e_config_rss(struct i40e_pf *pf)
(reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512); (reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512);
wr32(hw, I40E_PFQF_CTL_0, reg_val); wr32(hw, I40E_PFQF_CTL_0, reg_val);
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
return i40e_config_rss_aq(pf->vsi[pf->lan_vsi], seed); if (!lut)
else return -ENOMEM;
return i40e_config_rss_reg(pf, seed);
i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size);
kfree(lut);
return ret;
} }
/** /**
...@@ -7938,7 +8063,7 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count) ...@@ -7938,7 +8063,7 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
pf->rss_size = new_rss_size; pf->rss_size = new_rss_size;
i40e_reset_and_rebuild(pf, true); i40e_reset_and_rebuild(pf, true);
i40e_config_rss(pf); i40e_pf_config_rss(pf);
} }
dev_info(&pf->pdev->dev, "RSS count: %d\n", pf->rss_size); dev_info(&pf->pdev->dev, "RSS count: %d\n", pf->rss_size);
return pf->rss_size; return pf->rss_size;
...@@ -9947,7 +10072,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) ...@@ -9947,7 +10072,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
* the hash * the hash
*/ */
if ((pf->flags & I40E_FLAG_RSS_ENABLED)) if ((pf->flags & I40E_FLAG_RSS_ENABLED))
i40e_config_rss(pf); i40e_pf_config_rss(pf);
/* fill in link information and enable LSE reporting */ /* fill in link information and enable LSE reporting */
i40e_update_link_info(&pf->hw); i40e_update_link_info(&pf->hw);
...@@ -10111,10 +10236,12 @@ static int i40e_setup_pf_filter_control(struct i40e_pf *pf) ...@@ -10111,10 +10236,12 @@ static int i40e_setup_pf_filter_control(struct i40e_pf *pf)
} }
#define INFO_STRING_LEN 255 #define INFO_STRING_LEN 255
#define REMAIN(__x) (INFO_STRING_LEN - (__x))
static void i40e_print_features(struct i40e_pf *pf) static void i40e_print_features(struct i40e_pf *pf)
{ {
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
char *buf, *string; char *buf, *string;
int i = 0;
string = kzalloc(INFO_STRING_LEN, GFP_KERNEL); string = kzalloc(INFO_STRING_LEN, GFP_KERNEL);
if (!string) { if (!string) {
...@@ -10124,42 +10251,42 @@ static void i40e_print_features(struct i40e_pf *pf) ...@@ -10124,42 +10251,42 @@ static void i40e_print_features(struct i40e_pf *pf)
buf = string; buf = string;
buf += sprintf(string, "Features: PF-id[%d] ", hw->pf_id); i += snprintf(&buf[i], REMAIN(i), "Features: PF-id[%d] ", hw->pf_id);
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
buf += sprintf(buf, "VFs: %d ", pf->num_req_vfs); i += snprintf(&buf[i], REMAIN(i), "VFs: %d ", pf->num_req_vfs);
#endif #endif
buf += sprintf(buf, "VSIs: %d QP: %d RX: %s ", i += snprintf(&buf[i], REMAIN(i), "VSIs: %d QP: %d RX: %s ",
pf->hw.func_caps.num_vsis, pf->hw.func_caps.num_vsis,
pf->vsi[pf->lan_vsi]->num_queue_pairs, pf->vsi[pf->lan_vsi]->num_queue_pairs,
pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF"); pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF");
if (pf->flags & I40E_FLAG_RSS_ENABLED) if (pf->flags & I40E_FLAG_RSS_ENABLED)
buf += sprintf(buf, "RSS "); i += snprintf(&buf[i], REMAIN(i), "RSS ");
if (pf->flags & I40E_FLAG_FD_ATR_ENABLED) if (pf->flags & I40E_FLAG_FD_ATR_ENABLED)
buf += sprintf(buf, "FD_ATR "); i += snprintf(&buf[i], REMAIN(i), "FD_ATR ");
if (pf->flags & I40E_FLAG_FD_SB_ENABLED) { if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
buf += sprintf(buf, "FD_SB "); i += snprintf(&buf[i], REMAIN(i), "FD_SB ");
buf += sprintf(buf, "NTUPLE "); i += snprintf(&buf[i], REMAIN(i), "NTUPLE ");
} }
if (pf->flags & I40E_FLAG_DCB_CAPABLE) if (pf->flags & I40E_FLAG_DCB_CAPABLE)
buf += sprintf(buf, "DCB "); i += snprintf(&buf[i], REMAIN(i), "DCB ");
#if IS_ENABLED(CONFIG_VXLAN) #if IS_ENABLED(CONFIG_VXLAN)
buf += sprintf(buf, "VxLAN "); i += snprintf(&buf[i], REMAIN(i), "VxLAN ");
#endif #endif
if (pf->flags & I40E_FLAG_PTP) if (pf->flags & I40E_FLAG_PTP)
buf += sprintf(buf, "PTP "); i += snprintf(&buf[i], REMAIN(i), "PTP ");
#ifdef I40E_FCOE #ifdef I40E_FCOE
if (pf->flags & I40E_FLAG_FCOE_ENABLED) if (pf->flags & I40E_FLAG_FCOE_ENABLED)
buf += sprintf(buf, "FCOE "); i += snprintf(&buf[i], REMAIN(i), "FCOE ");
#endif #endif
if (pf->flags & I40E_FLAG_VEB_MODE_ENABLED) if (pf->flags & I40E_FLAG_VEB_MODE_ENABLED)
buf += sprintf(buf, "VEB "); i += snprintf(&buf[i], REMAIN(i), "VEPA ");
else else
buf += sprintf(buf, "VEPA "); buf += sprintf(buf, "VEPA ");
BUG_ON(buf > (string + INFO_STRING_LEN));
dev_info(&pf->pdev->dev, "%s\n", string); dev_info(&pf->pdev->dev, "%s\n", string);
kfree(string); kfree(string);
WARN_ON(i > INFO_STRING_LEN);
} }
/** /**
...@@ -10183,6 +10310,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -10183,6 +10310,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u16 link_status; u16 link_status;
int err; int err;
u32 len; u32 len;
u32 val;
u32 i; u32 i;
u8 set_fc_aq_fail; u8 set_fc_aq_fail;
...@@ -10487,6 +10615,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -10487,6 +10615,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_stat_str(&pf->hw, err), i40e_stat_str(&pf->hw, err),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
/* Reconfigure hardware for allowing smaller MSS in the case
* of TSO, so that we avoid the MDD being fired and causing
* a reset in the case of small MSS+TSO.
*/
val = rd32(hw, I40E_REG_MSS);
if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
val &= ~I40E_REG_MSS_MIN_MASK;
val |= I40E_64BYTE_MSS;
wr32(hw, I40E_REG_MSS, val);
}
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) || if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
(pf->hw.aq.fw_maj_ver < 4)) { (pf->hw.aq.fw_maj_ver < 4)) {
msleep(75); msleep(75);
......
...@@ -1925,8 +1925,10 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) ...@@ -1925,8 +1925,10 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
/* If work not completed, return budget and polling will return */ /* If work not completed, return budget and polling will return */
if (!clean_complete) { if (!clean_complete) {
tx_only: tx_only:
if (arm_wb) if (arm_wb) {
q_vector->tx.ring[0].tx_stats.tx_force_wb++;
i40e_force_wb(vsi, q_vector); i40e_force_wb(vsi, q_vector);
}
return budget; return budget;
} }
...@@ -2186,14 +2188,12 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, ...@@ -2186,14 +2188,12 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
* @tx_ring: ptr to the ring to send * @tx_ring: ptr to the ring to send
* @skb: ptr to the skb we're sending * @skb: ptr to the skb we're sending
* @hdr_len: ptr to the size of the packet header * @hdr_len: ptr to the size of the packet header
* @cd_type_cmd_tso_mss: ptr to u64 object * @cd_type_cmd_tso_mss: Quad Word 1
* @cd_tunneling: ptr to context descriptor bits
* *
* Returns 0 if no TSO can happen, 1 if tso is going, or error * Returns 0 if no TSO can happen, 1 if tso is going, or error
**/ **/
static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
u8 *hdr_len, u64 *cd_type_cmd_tso_mss, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
u32 *cd_tunneling)
{ {
u32 cd_cmd, cd_tso_len, cd_mss; u32 cd_cmd, cd_tso_len, cd_mss;
struct ipv6hdr *ipv6h; struct ipv6hdr *ipv6h;
...@@ -2246,7 +2246,7 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -2246,7 +2246,7 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
* @tx_ring: ptr to the ring to send * @tx_ring: ptr to the ring to send
* @skb: ptr to the skb we're sending * @skb: ptr to the skb we're sending
* @tx_flags: the collected send information * @tx_flags: the collected send information
* @cd_type_cmd_tso_mss: ptr to u64 object * @cd_type_cmd_tso_mss: Quad Word 1
* *
* Returns 0 if no Tx timestamp can happen and 1 if the timestamp will happen * Returns 0 if no Tx timestamp can happen and 1 if the timestamp will happen
**/ **/
...@@ -2825,8 +2825,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, ...@@ -2825,8 +2825,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
else if (protocol == htons(ETH_P_IPV6)) else if (protocol == htons(ETH_P_IPV6))
tx_flags |= I40E_TX_FLAGS_IPV6; tx_flags |= I40E_TX_FLAGS_IPV6;
tso = i40e_tso(tx_ring, skb, &hdr_len, tso = i40e_tso(tx_ring, skb, &hdr_len, &cd_type_cmd_tso_mss);
&cd_type_cmd_tso_mss, &cd_tunneling);
if (tso < 0) if (tso < 0)
goto out_drop; goto out_drop;
......
...@@ -202,6 +202,7 @@ struct i40e_tx_queue_stats { ...@@ -202,6 +202,7 @@ struct i40e_tx_queue_stats {
u64 tx_busy; u64 tx_busy;
u64 tx_done_old; u64 tx_done_old;
u64 tx_linearize; u64 tx_linearize;
u64 tx_force_wb;
}; };
struct i40e_rx_queue_stats { struct i40e_rx_queue_stats {
......
...@@ -1623,7 +1623,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1623,7 +1623,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
if (!f) { if (!f) {
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"Unable to add VF MAC filter\n"); "Unable to add MAC filter %pM for VF %d\n",
al->list[i].addr, vf->vf_id);
ret = I40E_ERR_PARAM; ret = I40E_ERR_PARAM;
spin_unlock_bh(&vsi->mac_filter_list_lock); spin_unlock_bh(&vsi->mac_filter_list_lock);
goto error_param; goto error_param;
...@@ -1633,7 +1634,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1633,7 +1634,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
/* program the updated filter list */ /* program the updated filter list */
if (i40e_sync_vsi_filters(vsi, false)) if (i40e_sync_vsi_filters(vsi, false))
dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n"); dev_err(&pf->pdev->dev, "Unable to program VF %d MAC filters\n",
vf->vf_id);
error_param: error_param:
/* send the response to the VF */ /* send the response to the VF */
...@@ -1669,8 +1671,8 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1669,8 +1671,8 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
for (i = 0; i < al->num_elements; i++) { for (i = 0; i < al->num_elements; i++) {
if (is_broadcast_ether_addr(al->list[i].addr) || if (is_broadcast_ether_addr(al->list[i].addr) ||
is_zero_ether_addr(al->list[i].addr)) { is_zero_ether_addr(al->list[i].addr)) {
dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n", dev_err(&pf->pdev->dev, "Invalid MAC addr %pM for VF %d\n",
al->list[i].addr); al->list[i].addr, vf->vf_id);
ret = I40E_ERR_INVALID_MAC_ADDR; ret = I40E_ERR_INVALID_MAC_ADDR;
goto error_param; goto error_param;
} }
...@@ -1686,7 +1688,8 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1686,7 +1688,8 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
/* program the updated filter list */ /* program the updated filter list */
if (i40e_sync_vsi_filters(vsi, false)) if (i40e_sync_vsi_filters(vsi, false))
dev_err(&pf->pdev->dev, "Unable to program VF MAC filters\n"); dev_err(&pf->pdev->dev, "Unable to program VF %d MAC filters\n",
vf->vf_id);
error_param: error_param:
/* send the response to the VF */ /* send the response to the VF */
...@@ -1740,8 +1743,8 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1740,8 +1743,8 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
if (ret) if (ret)
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"Unable to add VF vlan filter %d, error %d\n", "Unable to add VLAN filter %d for VF %d, error %d\n",
vfl->vlan_id[i], ret); vfl->vlan_id[i], vf->vf_id, ret);
} }
error_param: error_param:
...@@ -1792,8 +1795,8 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen) ...@@ -1792,8 +1795,8 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
if (ret) if (ret)
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"Unable to delete VF vlan filter %d, error %d\n", "Unable to delete VLAN filter %d for VF %d, error %d\n",
vfl->vlan_id[i], ret); vfl->vlan_id[i], vf->vf_id, ret);
} }
error_param: error_param:
......
...@@ -2311,4 +2311,4 @@ struct i40e_aqc_debug_modify_internals { ...@@ -2311,4 +2311,4 @@ struct i40e_aqc_debug_modify_internals {
I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals); I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals);
#endif #endif /* _I40E_ADMINQ_CMD_H_ */
...@@ -1363,8 +1363,10 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget) ...@@ -1363,8 +1363,10 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)
/* If work not completed, return budget and polling will return */ /* If work not completed, return budget and polling will return */
if (!clean_complete) { if (!clean_complete) {
tx_only: tx_only:
if (arm_wb) if (arm_wb) {
q_vector->tx.ring[0].tx_stats.tx_force_wb++;
i40evf_force_wb(vsi, q_vector); i40evf_force_wb(vsi, q_vector);
}
return budget; return budget;
} }
...@@ -1436,13 +1438,12 @@ static inline int i40evf_tx_prepare_vlan_flags(struct sk_buff *skb, ...@@ -1436,13 +1438,12 @@ static inline int i40evf_tx_prepare_vlan_flags(struct sk_buff *skb,
* @tx_ring: ptr to the ring to send * @tx_ring: ptr to the ring to send
* @skb: ptr to the skb we're sending * @skb: ptr to the skb we're sending
* @hdr_len: ptr to the size of the packet header * @hdr_len: ptr to the size of the packet header
* @cd_tunneling: ptr to context descriptor bits * @cd_type_cmd_tso_mss: Quad Word 1
* *
* Returns 0 if no TSO can happen, 1 if tso is going, or error * Returns 0 if no TSO can happen, 1 if tso is going, or error
**/ **/
static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
u8 *hdr_len, u64 *cd_type_cmd_tso_mss, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
u32 *cd_tunneling)
{ {
u32 cd_cmd, cd_tso_len, cd_mss; u32 cd_cmd, cd_tso_len, cd_mss;
struct ipv6hdr *ipv6h; struct ipv6hdr *ipv6h;
...@@ -1979,8 +1980,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, ...@@ -1979,8 +1980,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
else if (protocol == htons(ETH_P_IPV6)) else if (protocol == htons(ETH_P_IPV6))
tx_flags |= I40E_TX_FLAGS_IPV6; tx_flags |= I40E_TX_FLAGS_IPV6;
tso = i40e_tso(tx_ring, skb, &hdr_len, tso = i40e_tso(tx_ring, skb, &hdr_len, &cd_type_cmd_tso_mss);
&cd_type_cmd_tso_mss, &cd_tunneling);
if (tso < 0) if (tso < 0)
goto out_drop; goto out_drop;
......
...@@ -201,6 +201,7 @@ struct i40e_tx_queue_stats { ...@@ -201,6 +201,7 @@ struct i40e_tx_queue_stats {
u64 tx_busy; u64 tx_busy;
u64 tx_done_old; u64 tx_done_old;
u64 tx_linearize; u64 tx_linearize;
u64 tx_force_wb;
}; };
struct i40e_rx_queue_stats { struct i40e_rx_queue_stats {
......
...@@ -391,6 +391,7 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter) ...@@ -391,6 +391,7 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
struct i40e_virtchnl_ether_addr_list *veal; struct i40e_virtchnl_ether_addr_list *veal;
int len, i = 0, count = 0; int len, i = 0, count = 0;
struct i40evf_mac_filter *f; struct i40evf_mac_filter *f;
bool more = false;
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */ /* bail because we already have a command pending */
...@@ -415,7 +416,9 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter) ...@@ -415,7 +416,9 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
count = (I40EVF_MAX_AQ_BUF_SIZE - count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_ether_addr_list)) / sizeof(struct i40e_virtchnl_ether_addr_list)) /
sizeof(struct i40e_virtchnl_ether_addr); sizeof(struct i40e_virtchnl_ether_addr);
len = I40EVF_MAX_AQ_BUF_SIZE; len = sizeof(struct i40e_virtchnl_ether_addr_list) +
(count * sizeof(struct i40e_virtchnl_ether_addr));
more = true;
} }
veal = kzalloc(len, GFP_ATOMIC); veal = kzalloc(len, GFP_ATOMIC);
...@@ -431,7 +434,8 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter) ...@@ -431,7 +434,8 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
f->add = false; f->add = false;
} }
} }
adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER; if (!more)
adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS, i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
(u8 *)veal, len); (u8 *)veal, len);
kfree(veal); kfree(veal);
...@@ -450,6 +454,7 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter) ...@@ -450,6 +454,7 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
struct i40e_virtchnl_ether_addr_list *veal; struct i40e_virtchnl_ether_addr_list *veal;
struct i40evf_mac_filter *f, *ftmp; struct i40evf_mac_filter *f, *ftmp;
int len, i = 0, count = 0; int len, i = 0, count = 0;
bool more = false;
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */ /* bail because we already have a command pending */
...@@ -474,7 +479,9 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter) ...@@ -474,7 +479,9 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
count = (I40EVF_MAX_AQ_BUF_SIZE - count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_ether_addr_list)) / sizeof(struct i40e_virtchnl_ether_addr_list)) /
sizeof(struct i40e_virtchnl_ether_addr); sizeof(struct i40e_virtchnl_ether_addr);
len = I40EVF_MAX_AQ_BUF_SIZE; len = sizeof(struct i40e_virtchnl_ether_addr_list) +
(count * sizeof(struct i40e_virtchnl_ether_addr));
more = true;
} }
veal = kzalloc(len, GFP_ATOMIC); veal = kzalloc(len, GFP_ATOMIC);
if (!veal) if (!veal)
...@@ -490,7 +497,8 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter) ...@@ -490,7 +497,8 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
kfree(f); kfree(f);
} }
} }
adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER; if (!more)
adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS, i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
(u8 *)veal, len); (u8 *)veal, len);
kfree(veal); kfree(veal);
...@@ -509,6 +517,7 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter) ...@@ -509,6 +517,7 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
struct i40e_virtchnl_vlan_filter_list *vvfl; struct i40e_virtchnl_vlan_filter_list *vvfl;
int len, i = 0, count = 0; int len, i = 0, count = 0;
struct i40evf_vlan_filter *f; struct i40evf_vlan_filter *f;
bool more = false;
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */ /* bail because we already have a command pending */
...@@ -534,7 +543,9 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter) ...@@ -534,7 +543,9 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
count = (I40EVF_MAX_AQ_BUF_SIZE - count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_vlan_filter_list)) / sizeof(struct i40e_virtchnl_vlan_filter_list)) /
sizeof(u16); sizeof(u16);
len = I40EVF_MAX_AQ_BUF_SIZE; len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
(count * sizeof(u16));
more = true;
} }
vvfl = kzalloc(len, GFP_ATOMIC); vvfl = kzalloc(len, GFP_ATOMIC);
if (!vvfl) if (!vvfl)
...@@ -549,7 +560,8 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter) ...@@ -549,7 +560,8 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
f->add = false; f->add = false;
} }
} }
adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER; if (!more)
adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len); i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
kfree(vvfl); kfree(vvfl);
} }
...@@ -567,6 +579,7 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter) ...@@ -567,6 +579,7 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
struct i40e_virtchnl_vlan_filter_list *vvfl; struct i40e_virtchnl_vlan_filter_list *vvfl;
struct i40evf_vlan_filter *f, *ftmp; struct i40evf_vlan_filter *f, *ftmp;
int len, i = 0, count = 0; int len, i = 0, count = 0;
bool more = false;
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */ /* bail because we already have a command pending */
...@@ -592,7 +605,9 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter) ...@@ -592,7 +605,9 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
count = (I40EVF_MAX_AQ_BUF_SIZE - count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_vlan_filter_list)) / sizeof(struct i40e_virtchnl_vlan_filter_list)) /
sizeof(u16); sizeof(u16);
len = I40EVF_MAX_AQ_BUF_SIZE; len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
(count * sizeof(u16));
more = true;
} }
vvfl = kzalloc(len, GFP_ATOMIC); vvfl = kzalloc(len, GFP_ATOMIC);
if (!vvfl) if (!vvfl)
...@@ -608,7 +623,8 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter) ...@@ -608,7 +623,8 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
kfree(f); kfree(f);
} }
} }
adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER; if (!more)
adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len); i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
kfree(vvfl); kfree(vvfl);
} }
...@@ -724,9 +740,29 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, ...@@ -724,9 +740,29 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
return; return;
} }
if (v_retval) { if (v_retval) {
dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n", switch (v_opcode) {
v_retval, i40evf_stat_str(&adapter->hw, v_retval), case I40E_VIRTCHNL_OP_ADD_VLAN:
v_opcode); dev_err(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
i40evf_stat_str(&adapter->hw, v_retval));
break;
case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS:
dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n",
i40evf_stat_str(&adapter->hw, v_retval));
break;
case I40E_VIRTCHNL_OP_DEL_VLAN:
dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n",
i40evf_stat_str(&adapter->hw, v_retval));
break;
case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS:
dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
i40evf_stat_str(&adapter->hw, v_retval));
break;
default:
dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
v_retval,
i40evf_stat_str(&adapter->hw, v_retval),
v_opcode);
}
} }
switch (v_opcode) { switch (v_opcode) {
case I40E_VIRTCHNL_OP_GET_STATS: { case I40E_VIRTCHNL_OP_GET_STATS: {
......
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