Skip to content

Commit

Permalink
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2018-02-13

This series contains updates to i40e and i40evf.

Wei Yongjun fixes a function that needed to be "static".  Also fixes the
use of GFP_KERNEL to GFP_ATOMIC when we have taken a spinlock.

Mitch cleans up several info messages to not include the memory
addresses being used on the off chance this information could be used
maliciously.

Alan provides several fixes to the broadcast filters starting with the
triggering of overflow promiscuous in circumstances where we run out of
space for broadcast filters to prevent traffic from being unexpectedly
dropped.  Refactored the code to improve the readability and
maintainability when we are concerned about when and how overflow
promiscuous is changed.

Harshitha cleans up a message to make it more clear on what is being
reset, so users are not confused and think the PF is resetting.

Dave fixes an issue where the MAC, firmware version and NPAR checks used
to determine if shutting off the firmware LLDP engine is supported or
not, instead set a hardware flag which ethtool can use.

Jake updates the VF driver to use __dev_uc_sync and __dev_mc_sync, like
the PF driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 14, 2018
2 parents 153e1b8 + 693acdd commit 7707968
Showing 6 changed files with 119 additions and 138 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
@@ -507,6 +507,7 @@ struct i40e_pf {
#define I40E_HW_STOP_FW_LLDP BIT(16)
#define I40E_HW_PORT_ID_VALID BIT(17)
#define I40E_HW_RESTART_AUTONEG BIT(18)
#define I40E_HW_STOPPABLE_FW_LLDP BIT(19)

u64 flags;
#define I40E_FLAG_RX_CSUM_ENABLED BIT_ULL(0)
40 changes: 6 additions & 34 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
@@ -155,8 +155,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
dev_info(&pf->pdev->dev, " vlan_features = 0x%08lx\n",
(unsigned long int)nd->vlan_features);
}
dev_info(&pf->pdev->dev,
" vlgrp: & = %p\n", vsi->active_vlans);
dev_info(&pf->pdev->dev, " active_vlans is %s\n",
vsi->active_vlans ? "<valid>" : "<null>");
dev_info(&pf->pdev->dev,
" flags = 0x%08lx, netdev_registered = %i, current_netdev_flags = 0x%04x\n",
vsi->flags, vsi->netdev_registered, vsi->current_netdev_flags);
@@ -269,14 +269,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
if (!rx_ring)
continue;

dev_info(&pf->pdev->dev,
" rx_rings[%i]: desc = %p\n",
i, rx_ring->desc);
dev_info(&pf->pdev->dev,
" rx_rings[%i]: dev = %p, netdev = %p, rx_bi = %p\n",
i, rx_ring->dev,
rx_ring->netdev,
rx_ring->rx_bi);
dev_info(&pf->pdev->dev,
" rx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n",
i, *rx_ring->state,
@@ -307,13 +299,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
rx_ring->rx_stats.realloc_count,
rx_ring->rx_stats.page_reuse_count);
dev_info(&pf->pdev->dev,
" rx_rings[%i]: size = %i, dma = 0x%08lx\n",
i, rx_ring->size,
(unsigned long int)rx_ring->dma);
dev_info(&pf->pdev->dev,
" rx_rings[%i]: vsi = %p, q_vector = %p\n",
i, rx_ring->vsi,
rx_ring->q_vector);
" rx_rings[%i]: size = %i\n",
i, rx_ring->size);
dev_info(&pf->pdev->dev,
" rx_rings[%i]: itr_setting = %d (%s)\n",
i, rx_ring->itr_setting,
@@ -325,14 +312,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
if (!tx_ring)
continue;

dev_info(&pf->pdev->dev,
" tx_rings[%i]: desc = %p\n",
i, tx_ring->desc);
dev_info(&pf->pdev->dev,
" tx_rings[%i]: dev = %p, netdev = %p, tx_bi = %p\n",
i, tx_ring->dev,
tx_ring->netdev,
tx_ring->tx_bi);
dev_info(&pf->pdev->dev,
" tx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n",
i, *tx_ring->state,
@@ -355,13 +334,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
tx_ring->tx_stats.tx_busy,
tx_ring->tx_stats.tx_done_old);
dev_info(&pf->pdev->dev,
" tx_rings[%i]: size = %i, dma = 0x%08lx\n",
i, tx_ring->size,
(unsigned long int)tx_ring->dma);
dev_info(&pf->pdev->dev,
" tx_rings[%i]: vsi = %p, q_vector = %p\n",
i, tx_ring->vsi,
tx_ring->q_vector);
" tx_rings[%i]: size = %i\n",
i, tx_ring->size);
dev_info(&pf->pdev->dev,
" tx_rings[%i]: DCB tc = %d\n",
i, tx_ring->dcb_tc);
@@ -466,8 +440,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
vsi->info.resp_reserved[6], vsi->info.resp_reserved[7],
vsi->info.resp_reserved[8], vsi->info.resp_reserved[9],
vsi->info.resp_reserved[10], vsi->info.resp_reserved[11]);
if (vsi->back)
dev_info(&pf->pdev->dev, " PF = %p\n", vsi->back);
dev_info(&pf->pdev->dev, " idx = %d\n", vsi->idx);
dev_info(&pf->pdev->dev,
" tc_config: numtc = %d, enabled_tc = 0x%x\n",
12 changes: 2 additions & 10 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
@@ -4426,17 +4426,9 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
* unsupported FW versions.
*/
if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
if (pf->hw.func_caps.npar_enable) {
if (!(pf->hw_features & I40E_HW_STOPPABLE_FW_LLDP)) {
dev_warn(&pf->pdev->dev,
"Unable to change FW LLDP if NPAR active\n");
return -EOPNOTSUPP;
}

if (pf->hw.aq.api_maj_ver < 1 ||
(pf->hw.aq.api_maj_ver == 1 &&
pf->hw.aq.api_min_ver < 7)) {
dev_warn(&pf->pdev->dev,
"FW ver does not support changing FW LLDP\n");
"Device does not support changing FW LLDP\n");
return -EOPNOTSUPP;
}
}
88 changes: 42 additions & 46 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
@@ -215,8 +215,8 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile,

if (!pile || needed == 0 || id >= I40E_PILE_VALID_BIT) {
dev_info(&pf->pdev->dev,
"param err: pile=%p needed=%d id=0x%04x\n",
pile, needed, id);
"param err: pile=%s needed=%d id=0x%04x\n",
pile ? "<valid>" : "<null>", needed, id);
return -EINVAL;
}

@@ -1380,14 +1380,7 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,

ether_addr_copy(f->macaddr, macaddr);
f->vlan = vlan;
/* If we're in overflow promisc mode, set the state directly
* to failed, so we don't bother to try sending the filter
* to the hardware.
*/
if (test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state))
f->state = I40E_FILTER_FAILED;
else
f->state = I40E_FILTER_NEW;
f->state = I40E_FILTER_NEW;
INIT_HLIST_NODE(&f->hlist);

key = i40e_addr_to_hkey(macaddr);
@@ -2116,17 +2109,16 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name,
* @list: the list of filters to send to firmware
* @add_head: Position in the add hlist
* @num_add: the number of filters to add
* @promisc_change: set to true on exit if promiscuous mode was forced on
*
* Send a request to firmware via AdminQ to add a chunk of filters. Will set
* promisc_changed to true if the firmware has run out of space for more
* filters.
* __I40E_VSI_OVERFLOW_PROMISC bit in vsi->state if the firmware has run out of
* space for more filters.
*/
static
void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
struct i40e_aqc_add_macvlan_element_data *list,
struct i40e_new_mac_filter *add_head,
int num_add, bool *promisc_changed)
int num_add)
{
struct i40e_hw *hw = &vsi->back->hw;
int aq_err, fcnt;
@@ -2136,7 +2128,6 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
fcnt = i40e_update_filter_state(num_add, list, add_head);

if (fcnt != num_add) {
*promisc_changed = true;
set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
dev_warn(&vsi->back->pdev->dev,
"Error %s adding RX filters on %s, promiscuous mode forced on\n",
@@ -2177,11 +2168,13 @@ i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
NULL);
}

if (aq_ret)
if (aq_ret) {
set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
dev_warn(&vsi->back->pdev->dev,
"Error %s setting broadcast promiscuous mode on %s\n",
"Error %s, forcing overflow promiscuous on %s\n",
i40e_aq_str(hw, hw->aq.asq_last_status),
vsi_name);
}

return aq_ret;
}
@@ -2267,9 +2260,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
struct i40e_mac_filter *f;
struct i40e_new_mac_filter *new, *add_head = NULL;
struct i40e_hw *hw = &vsi->back->hw;
bool old_overflow, new_overflow;
unsigned int failed_filters = 0;
unsigned int vlan_filters = 0;
bool promisc_changed = false;
char vsi_name[16] = "PF";
int filter_list_len = 0;
i40e_status aq_ret = 0;
@@ -2291,6 +2284,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
usleep_range(1000, 2000);
pf = vsi->back;

old_overflow = test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);

if (vsi->netdev) {
changed_flags = vsi->current_netdev_flags ^ vsi->netdev->flags;
vsi->current_netdev_flags = vsi->netdev->flags;
@@ -2423,12 +2418,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)

num_add = 0;
hlist_for_each_entry_safe(new, h, &tmp_add_list, hlist) {
if (test_bit(__I40E_VSI_OVERFLOW_PROMISC,
vsi->state)) {
new->state = I40E_FILTER_FAILED;
continue;
}

/* handle broadcast filters by updating the broadcast
* promiscuous flag instead of adding a MAC filter.
*/
@@ -2464,15 +2453,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
/* flush a full buffer */
if (num_add == filter_list_len) {
i40e_aqc_add_filters(vsi, vsi_name, add_list,
add_head, num_add,
&promisc_changed);
add_head, num_add);
memset(add_list, 0, list_size);
num_add = 0;
}
}
if (num_add) {
i40e_aqc_add_filters(vsi, vsi_name, add_list, add_head,
num_add, &promisc_changed);
num_add);
}
/* Now move all of the filters from the temp add list back to
* the VSI's list.
@@ -2501,24 +2489,16 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
}
spin_unlock_bh(&vsi->mac_filter_hash_lock);

/* If promiscuous mode has changed, we need to calculate a new
* threshold for when we are safe to exit
*/
if (promisc_changed)
vsi->promisc_threshold = (vsi->active_filters * 3) / 4;

/* Check if we are able to exit overflow promiscuous mode. We can
* safely exit if we didn't just enter, we no longer have any failed
* filters, and we have reduced filters below the threshold value.
*/
if (test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state) &&
!promisc_changed && !failed_filters &&
(vsi->active_filters < vsi->promisc_threshold)) {
if (old_overflow && !failed_filters &&
vsi->active_filters < vsi->promisc_threshold) {
dev_info(&pf->pdev->dev,
"filter logjam cleared on %s, leaving overflow promiscuous mode\n",
vsi_name);
clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
promisc_changed = true;
vsi->promisc_threshold = 0;
}

@@ -2528,6 +2508,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
goto out;
}

new_overflow = test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);

/* If we are entering overflow promiscuous, we need to calculate a new
* threshold for when we are safe to exit
*/
if (!old_overflow && new_overflow)
vsi->promisc_threshold = (vsi->active_filters * 3) / 4;

/* check for changes in promiscuous modes */
if (changed_flags & IFF_ALLMULTI) {
bool cur_multipromisc;
@@ -2548,12 +2536,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
}
}

if ((changed_flags & IFF_PROMISC) || promisc_changed) {
if ((changed_flags & IFF_PROMISC) || old_overflow != new_overflow) {
bool cur_promisc;

cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) ||
test_bit(__I40E_VSI_OVERFLOW_PROMISC,
vsi->state));
new_overflow);
aq_ret = i40e_set_promiscuous(pf, cur_promisc);
if (aq_ret) {
retval = i40e_aq_rc_to_posix(aq_ret,
@@ -5381,7 +5368,7 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
* @vsi: VSI to be configured
*
**/
int i40e_get_link_speed(struct i40e_vsi *vsi)
static int i40e_get_link_speed(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;

@@ -9954,18 +9941,17 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi)

mutex_lock(&pf->switch_mutex);
if (!pf->vsi[vsi->idx]) {
dev_err(&pf->pdev->dev, "pf->vsi[%d] is NULL, just free vsi[%d](%p,type %d)\n",
vsi->idx, vsi->idx, vsi, vsi->type);
dev_err(&pf->pdev->dev, "pf->vsi[%d] is NULL, just free vsi[%d](type %d)\n",
vsi->idx, vsi->idx, vsi->type);
goto unlock_vsi;
}

if (pf->vsi[vsi->idx] != vsi) {
dev_err(&pf->pdev->dev,
"pf->vsi[%d](%p, type %d) != vsi[%d](%p,type %d): no free!\n",
"pf->vsi[%d](type %d) != vsi[%d](type %d): no free!\n",
pf->vsi[vsi->idx]->idx,
pf->vsi[vsi->idx],
pf->vsi[vsi->idx]->type,
vsi->idx, vsi, vsi->type);
vsi->idx, vsi->type);
goto unlock_vsi;
}

@@ -11103,6 +11089,16 @@ static int i40e_sw_init(struct i40e_pf *pf)
/* IWARP needs one extra vector for CQP just like MISC.*/
pf->num_iwarp_msix = (int)num_online_cpus() + 1;
}
/* Stopping the FW LLDP engine is only supported on the
* XL710 with a FW ver >= 1.7. Also, stopping FW LLDP
* engine is not supported if NPAR is functioning on this
* part
*/
if (pf->hw.mac.type == I40E_MAC_XL710 &&
!pf->hw.func_caps.npar_enable &&
(pf->hw.aq.api_maj_ver > 1 ||
(pf->hw.aq.api_maj_ver == 1 && pf->hw.aq.api_min_ver > 6)))
pf->hw_features |= I40E_HW_STOPPABLE_FW_LLDP;

#ifdef CONFIG_PCI_IOV
if (pf->hw.func_caps.num_vfs && pf->hw.partition_id == 1) {
Loading

0 comments on commit 7707968

Please sign in to comment.