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 2016-10-31

This series contains updates to i40e and i40evf.

Colin Ian King fixes a minor issue with dev_err message where a new line
character was missing from the end of the message.

Jake provides several most of the changes in the series, starting with
dropping the is_vf and is_netdev fields in the i40e_mac_filter structure
since they are not needed (along with the checks that used these fields).
Reason being that we use separate VSI's for SRIOV VFs and for netdev VSIs,
therefore a single VSI should only have one type of filter.  Then
simplifies our .set_rx_mode handler by using the kernel provided
__dev_uc_sync and __dev_mc_sync functions for notification of add and
deletion of filters.  Refactored the i40e_put_mac_in_vlan() to resolve
an issue where this function was arbitrarily modifying all filters to
have the same VLAN, which is incorrect because it could be modifying
active filters without putting them into the new state.  Refactored the
delete filter logic so that we can re-use the functionality, where
appropriate, without having to search for the filter twice.  Reduced the
latency of operations related to searching for specific MAC filters by
using a static hash table instead of a list.  Reduced code duplication
in the adminq command to add/delete for filters.  Fixed an issue where
TSYNVALID bit was not being checked as the true indicator of whether
the packet has an associated timestamp.  Cleaned up a second msleep()
call by simply re-ordering the code so that the extra wait is no longer
needed.

Alan provides additional fix to the work Jake has been doing to resolve
a bug where adding at least one VLAN and then removing all VLANs leaves
the MAC filters for the VSI with an incorrect value for the VID which
indicates the MAC filter's VLAN status.

Alex adds a common method for finding a VSI by type.  Also cleaned up
the logic for coalescing RS bits, which was convoluted and larger than
it needed to be.

Mitch fixes an issue with the failure to add filters when the VF driver
is reloaded by simply setting the number of filters to 0 when freeing
VF resources.

Maciej implements a I40E_NVMUPD_STATE_ERROR state for NVM update, so
that the driver has the ability to return NVM image write failure.

Filip removes unreachable code which was found using static analysis
where "if" statements were never in a "true/false" state, so clean up
unnecessary if statements.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 1, 2016
2 parents bd68a2a + 3aa7b74 commit c587094
Show file tree
Hide file tree
Showing 18 changed files with 867 additions and 850 deletions.
74 changes: 53 additions & 21 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/iommu.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/hashtable.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/ip.h>
Expand Down Expand Up @@ -428,11 +429,13 @@ struct i40e_pf {
struct ptp_clock_info ptp_caps;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long last_rx_ptp_check;
spinlock_t tmreg_lock; /* Used to protect the device time registers. */
struct mutex tmreg_lock; /* Used to protect the SYSTIME registers. */
u64 ptp_base_adj;
u32 tx_hwtstamp_timeouts;
u32 rx_hwtstamp_cleared;
u32 latch_event_flags;
spinlock_t ptp_rx_lock; /* Used to protect Rx timestamp registers. */
unsigned long latch_events[4];
bool ptp_tx;
bool ptp_rx;
u16 rss_table_size; /* HW RSS table size */
Expand All @@ -445,6 +448,20 @@ struct i40e_pf {
u16 phy_led_val;
};

/**
* i40e_mac_to_hkey - Convert a 6-byte MAC Address to a u64 hash key
* @macaddr: the MAC Address as the base key
*
* Simply copies the address and returns it as a u64 for hashing
**/
static inline u64 i40e_addr_to_hkey(const u8 *macaddr)
{
u64 key = 0;

ether_addr_copy((u8 *)&key, macaddr);
return key;
}

enum i40e_filter_state {
I40E_FILTER_INVALID = 0, /* Invalid state */
I40E_FILTER_NEW, /* New, not sent to FW yet */
Expand All @@ -454,13 +471,10 @@ enum i40e_filter_state {
/* There is no 'removed' state; the filter struct is freed */
};
struct i40e_mac_filter {
struct list_head list;
struct hlist_node hlist;
u8 macaddr[ETH_ALEN];
#define I40E_VLAN_ANY -1
s16 vlan;
u8 counter; /* number of instances of this filter */
bool is_vf; /* filter belongs to a VF */
bool is_netdev; /* filter belongs to a netdev */
enum i40e_filter_state state;
};

Expand Down Expand Up @@ -501,9 +515,11 @@ struct i40e_vsi {
#define I40E_VSI_FLAG_VEB_OWNER BIT(1)
unsigned long flags;

/* Per VSI lock to protect elements/list (MAC filter) */
spinlock_t mac_filter_list_lock;
struct list_head mac_filter_list;
/* Per VSI lock to protect elements/hash (MAC filter) */
spinlock_t mac_filter_hash_lock;
/* Fixed size hash table with 2^8 buckets for MAC filters */
DECLARE_HASHTABLE(mac_filter_hash, 8);
bool has_vlan_filter;

/* VSI stats */
struct rtnl_link_stats64 net_stats;
Expand Down Expand Up @@ -707,6 +723,25 @@ int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut,
u16 rss_table_size, u16 rss_size);
struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
/**
* i40e_find_vsi_by_type - Find and return Flow Director VSI
* @pf: PF to search for VSI
* @type: Value indicating type of VSI we are looking for
**/
static inline struct i40e_vsi *
i40e_find_vsi_by_type(struct i40e_pf *pf, u16 type)
{
int i;

for (i = 0; i < pf->num_alloc_vsi; i++) {
struct i40e_vsi *vsi = pf->vsi[i];

if (vsi && vsi->type == type)
return vsi;
}

return NULL;
}
void i40e_update_stats(struct i40e_vsi *vsi);
void i40e_update_eth_stats(struct i40e_vsi *vsi);
struct rtnl_link_stats64 *i40e_get_vsi_stats_struct(struct i40e_vsi *vsi);
Expand All @@ -723,10 +758,8 @@ u32 i40e_get_global_fd_count(struct i40e_pf *pf);
bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
void i40e_set_ethtool_ops(struct net_device *netdev);
struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
u8 *macaddr, s16 vlan,
bool is_vf, bool is_netdev);
void i40e_del_filter(struct i40e_vsi *vsi, u8 *macaddr, s16 vlan,
bool is_vf, bool is_netdev);
const u8 *macaddr, s16 vlan);
void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan);
int i40e_sync_vsi_filters(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
u16 uplink, u32 param1);
Expand All @@ -740,7 +773,8 @@ void i40e_service_event_schedule(struct i40e_pf *pf);
void i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id,
u8 *msg, u16 len);

int i40e_vsi_control_rings(struct i40e_vsi *vsi, bool enable);
int i40e_vsi_start_rings(struct i40e_vsi *vsi);
void i40e_vsi_stop_rings(struct i40e_vsi *vsi);
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count);
struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid,
u16 downlink_seid, u8 enabled_tc);
Expand Down Expand Up @@ -816,14 +850,12 @@ int i40e_close(struct net_device *netdev);
int i40e_vsi_open(struct i40e_vsi *vsi);
void i40e_vlan_stripping_disable(struct i40e_vsi *vsi);
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid);
int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid);
struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid);
struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi,
const u8 *macaddr);
int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, const u8 *macaddr);
bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, const u8 *macaddr);
#ifdef I40E_FCOE
int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
struct tc_to_netdev *tc);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_adminq.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,11 +964,11 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc);
desc_idx = ntc;

hw->aq.arq_last_status =
(enum i40e_admin_queue_err)le16_to_cpu(desc->retval);
flags = le16_to_cpu(desc->flags);
if (flags & I40E_AQ_FLAG_ERR) {
ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
hw->aq.arq_last_status =
(enum i40e_admin_queue_err)le16_to_cpu(desc->retval);
i40e_debug(hw,
I40E_DEBUG_AQ_MESSAGE,
"AQRX: Event received with error 0x%X.\n",
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3313,8 +3313,10 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
/* partition id is 1-based, and functions are evenly spread
* across the ports as partitions
*/
hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
hw->num_partitions = num_functions / hw->num_ports;
if (hw->num_ports != 0) {
hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
hw->num_partitions = num_functions / hw->num_ports;
}

/* additional HW specific goodies that might
* someday be HW version specific
Expand Down
92 changes: 5 additions & 87 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
struct rtnl_link_stats64 *nstat;
struct i40e_mac_filter *f;
struct i40e_vsi *vsi;
int i;
int i, bkt;

vsi = i40e_dbg_find_vsi(pf, seid);
if (!vsi) {
Expand Down Expand Up @@ -166,11 +166,11 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
pf->hw.mac.addr,
pf->hw.mac.san_addr,
pf->hw.mac.port_addr);
list_for_each_entry(f, &vsi->mac_filter_list, list) {
hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
dev_info(&pf->pdev->dev,
" mac_filter_list: %pM vid=%d, is_netdev=%d is_vf=%d counter=%d, state %s\n",
f->macaddr, f->vlan, f->is_netdev, f->is_vf,
f->counter, i40e_filter_state_string[f->state]);
" mac_filter_hash: %pM vid=%d, state %s\n",
f->macaddr, f->vlan,
i40e_filter_state_string[f->state]);
}
dev_info(&pf->pdev->dev, " active_filters %d, promisc_threshold %d, overflow promisc %s\n",
vsi->active_filters, vsi->promisc_threshold,
Expand Down Expand Up @@ -867,86 +867,6 @@ static ssize_t i40e_dbg_command_write(struct file *filp,

dev_info(&pf->pdev->dev, "deleting relay %d\n", veb_seid);
i40e_veb_release(pf->veb[i]);

} else if (strncmp(cmd_buf, "add macaddr", 11) == 0) {
struct i40e_mac_filter *f;
int vlan = 0;
u8 ma[6];
int ret;

cnt = sscanf(&cmd_buf[11],
"%i %hhx:%hhx:%hhx:%hhx:%hhx:%hhx %i",
&vsi_seid,
&ma[0], &ma[1], &ma[2], &ma[3], &ma[4], &ma[5],
&vlan);
if (cnt == 7) {
vlan = 0;
} else if (cnt != 8) {
dev_info(&pf->pdev->dev,
"add macaddr: bad command string, cnt=%d\n",
cnt);
goto command_write_done;
}

vsi = i40e_dbg_find_vsi(pf, vsi_seid);
if (!vsi) {
dev_info(&pf->pdev->dev,
"add macaddr: VSI %d not found\n", vsi_seid);
goto command_write_done;
}

spin_lock_bh(&vsi->mac_filter_list_lock);
f = i40e_add_filter(vsi, ma, vlan, false, false);
spin_unlock_bh(&vsi->mac_filter_list_lock);
ret = i40e_sync_vsi_filters(vsi);
if (f && !ret)
dev_info(&pf->pdev->dev,
"add macaddr: %pM vlan=%d added to VSI %d\n",
ma, vlan, vsi_seid);
else
dev_info(&pf->pdev->dev,
"add macaddr: %pM vlan=%d to VSI %d failed, f=%p ret=%d\n",
ma, vlan, vsi_seid, f, ret);

} else if (strncmp(cmd_buf, "del macaddr", 11) == 0) {
int vlan = 0;
u8 ma[6];
int ret;

cnt = sscanf(&cmd_buf[11],
"%i %hhx:%hhx:%hhx:%hhx:%hhx:%hhx %i",
&vsi_seid,
&ma[0], &ma[1], &ma[2], &ma[3], &ma[4], &ma[5],
&vlan);
if (cnt == 7) {
vlan = 0;
} else if (cnt != 8) {
dev_info(&pf->pdev->dev,
"del macaddr: bad command string, cnt=%d\n",
cnt);
goto command_write_done;
}

vsi = i40e_dbg_find_vsi(pf, vsi_seid);
if (!vsi) {
dev_info(&pf->pdev->dev,
"del macaddr: VSI %d not found\n", vsi_seid);
goto command_write_done;
}

spin_lock_bh(&vsi->mac_filter_list_lock);
i40e_del_filter(vsi, ma, vlan, false, false);
spin_unlock_bh(&vsi->mac_filter_list_lock);
ret = i40e_sync_vsi_filters(vsi);
if (!ret)
dev_info(&pf->pdev->dev,
"del macaddr: %pM vlan=%d removed from VSI %d\n",
ma, vlan, vsi_seid);
else
dev_info(&pf->pdev->dev,
"del macaddr: %pM vlan=%d from VSI %d failed, ret=%d\n",
ma, vlan, vsi_seid, ret);

} else if (strncmp(cmd_buf, "add pvid", 8) == 0) {
i40e_status ret;
u16 vid;
Expand Down Expand Up @@ -1615,8 +1535,6 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, " del vsi [vsi_seid]\n");
dev_info(&pf->pdev->dev, " add relay <uplink_seid> <vsi_seid>\n");
dev_info(&pf->pdev->dev, " del relay <relay_seid>\n");
dev_info(&pf->pdev->dev, " add macaddr <vsi_seid> <aa:bb:cc:dd:ee:ff> [vlan]\n");
dev_info(&pf->pdev->dev, " del macaddr <vsi_seid> <aa:bb:cc:dd:ee:ff> [vlan]\n");
dev_info(&pf->pdev->dev, " add pvid <vsi_seid> <vid>\n");
dev_info(&pf->pdev->dev, " del pvid <vsi_seid>\n");
dev_info(&pf->pdev->dev, " dump switch\n");
Expand Down
30 changes: 1 addition & 29 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,13 @@ enum i40e_ethtool_test_id {
I40E_ETH_TEST_REG = 0,
I40E_ETH_TEST_EEPROM,
I40E_ETH_TEST_INTR,
I40E_ETH_TEST_LOOPBACK,
I40E_ETH_TEST_LINK,
};

static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
"Register test (offline)",
"Eeprom test (offline)",
"Interrupt test (offline)",
"Loopback test (offline)",
"Link test (on/offline)"
};

Expand Down Expand Up @@ -1744,17 +1742,6 @@ static int i40e_intr_test(struct net_device *netdev, u64 *data)
return *data;
}

static int i40e_loopback_test(struct net_device *netdev, u64 *data)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;

netif_info(pf, hw, netdev, "loopback test not implemented\n");
*data = 0;

return *data;
}

static inline bool i40e_active_vfs(struct i40e_pf *pf)
{
struct i40e_vf *vfs = pf->vf;
Expand All @@ -1768,17 +1755,7 @@ static inline bool i40e_active_vfs(struct i40e_pf *pf)

static inline bool i40e_active_vmdqs(struct i40e_pf *pf)
{
struct i40e_vsi **vsi = pf->vsi;
int i;

for (i = 0; i < pf->num_alloc_vsi; i++) {
if (!vsi[i])
continue;
if (vsi[i]->type == I40E_VSI_VMDQ2)
return true;
}

return false;
return !!i40e_find_vsi_by_type(pf, I40E_VSI_VMDQ2);
}

static void i40e_diag_test(struct net_device *netdev,
Expand All @@ -1800,7 +1777,6 @@ static void i40e_diag_test(struct net_device *netdev,
data[I40E_ETH_TEST_REG] = 1;
data[I40E_ETH_TEST_EEPROM] = 1;
data[I40E_ETH_TEST_INTR] = 1;
data[I40E_ETH_TEST_LOOPBACK] = 1;
data[I40E_ETH_TEST_LINK] = 1;
eth_test->flags |= ETH_TEST_FL_FAILED;
clear_bit(__I40E_TESTING, &pf->state);
Expand Down Expand Up @@ -1828,9 +1804,6 @@ static void i40e_diag_test(struct net_device *netdev,
if (i40e_intr_test(netdev, &data[I40E_ETH_TEST_INTR]))
eth_test->flags |= ETH_TEST_FL_FAILED;

if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
eth_test->flags |= ETH_TEST_FL_FAILED;

/* run reg test last, a reset is required after it */
if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
eth_test->flags |= ETH_TEST_FL_FAILED;
Expand All @@ -1851,7 +1824,6 @@ static void i40e_diag_test(struct net_device *netdev,
data[I40E_ETH_TEST_REG] = 0;
data[I40E_ETH_TEST_EEPROM] = 0;
data[I40E_ETH_TEST_INTR] = 0;
data[I40E_ETH_TEST_LOOPBACK] = 0;
}

skip_ol_tests:
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/intel/i40e/i40e_fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1522,12 +1522,12 @@ void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi)
* same PCI function.
*/
netdev->dev_port = 1;
spin_lock_bh(&vsi->mac_filter_list_lock);
i40e_add_filter(vsi, hw->mac.san_addr, 0, false, false);
i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0, false, false);
i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0, false, false);
i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0, false, false);
spin_unlock_bh(&vsi->mac_filter_list_lock);
spin_lock_bh(&vsi->mac_filter_hash_lock);
i40e_add_filter(vsi, hw->mac.san_addr, 0);
i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0);
i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0);
i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0);
spin_unlock_bh(&vsi->mac_filter_hash_lock);

/* use san mac */
ether_addr_copy(netdev->dev_addr, hw->mac.san_addr);
Expand Down
Loading

0 comments on commit c587094

Please sign in to comment.