Commit e72a7dd7 authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2018-05-09

This series contains updates to fm10k only.

Jake provides all the changes in the series, starting with adding
support for accelerated MACVLAN devices.  Reduced code duplication by
implementing a macro to be used when setting up the type specific
macros.  Avoided potential bugs with stats by using a macro to calculate
the array size when passing to ensure that the size is correct.

v2: changed macro reference '#' with __stringify() as suggested by
    Joe Perches to patch 2 of the series.  Also made sure the updated
    series of patches is actually pushed to my kernel.org tree
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9e575010 0a3e92de
...@@ -6,17 +6,27 @@ ...@@ -6,17 +6,27 @@
#include "fm10k.h" #include "fm10k.h"
struct fm10k_stats { struct fm10k_stats {
/* The stat_string is expected to be a format string formatted using
* vsnprintf by fm10k_add_stat_strings. Every member of a stats array
* should use the same format specifiers as they will be formatted
* using the same variadic arguments.
*/
char stat_string[ETH_GSTRING_LEN]; char stat_string[ETH_GSTRING_LEN];
int sizeof_stat; int sizeof_stat;
int stat_offset; int stat_offset;
}; };
#define FM10K_NETDEV_STAT(_net_stat) { \ #define FM10K_STAT_FIELDS(_type, _name, _stat) { \
.stat_string = #_net_stat, \ .stat_string = _name, \
.sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
.stat_offset = offsetof(struct net_device_stats, _net_stat) \ .stat_offset = offsetof(_type, _stat) \
} }
/* netdevice statistics */
#define FM10K_NETDEV_STAT(_net_stat) \
FM10K_STAT_FIELDS(struct net_device_stats, __stringify(_net_stat), \
_net_stat)
static const struct fm10k_stats fm10k_gstrings_net_stats[] = { static const struct fm10k_stats fm10k_gstrings_net_stats[] = {
FM10K_NETDEV_STAT(tx_packets), FM10K_NETDEV_STAT(tx_packets),
FM10K_NETDEV_STAT(tx_bytes), FM10K_NETDEV_STAT(tx_bytes),
...@@ -34,11 +44,9 @@ static const struct fm10k_stats fm10k_gstrings_net_stats[] = { ...@@ -34,11 +44,9 @@ static const struct fm10k_stats fm10k_gstrings_net_stats[] = {
#define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats) #define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats)
#define FM10K_STAT(_name, _stat) { \ /* General interface statistics */
.stat_string = _name, \ #define FM10K_STAT(_name, _stat) \
.sizeof_stat = FIELD_SIZEOF(struct fm10k_intfc, _stat), \ FM10K_STAT_FIELDS(struct fm10k_intfc, _name, _stat)
.stat_offset = offsetof(struct fm10k_intfc, _stat) \
}
static const struct fm10k_stats fm10k_gstrings_global_stats[] = { static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
FM10K_STAT("tx_restart_queue", restart_queue), FM10K_STAT("tx_restart_queue", restart_queue),
...@@ -75,11 +83,9 @@ static const struct fm10k_stats fm10k_gstrings_pf_stats[] = { ...@@ -75,11 +83,9 @@ static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
FM10K_STAT("nodesc_drop", stats.nodesc_drop.count), FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
}; };
#define FM10K_MBX_STAT(_name, _stat) { \ /* mailbox statistics */
.stat_string = _name, \ #define FM10K_MBX_STAT(_name, _stat) \
.sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \ FM10K_STAT_FIELDS(struct fm10k_mbx_info, _name, _stat)
.stat_offset = offsetof(struct fm10k_mbx_info, _stat) \
}
static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = { static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
FM10K_MBX_STAT("mbx_tx_busy", tx_busy), FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
...@@ -93,15 +99,13 @@ static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = { ...@@ -93,15 +99,13 @@ static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed), FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
}; };
#define FM10K_QUEUE_STAT(_name, _stat) { \ /* per-queue ring statistics */
.stat_string = _name, \ #define FM10K_QUEUE_STAT(_name, _stat) \
.sizeof_stat = FIELD_SIZEOF(struct fm10k_ring, _stat), \ FM10K_STAT_FIELDS(struct fm10k_ring, _name, _stat)
.stat_offset = offsetof(struct fm10k_ring, _stat) \
}
static const struct fm10k_stats fm10k_gstrings_queue_stats[] = { static const struct fm10k_stats fm10k_gstrings_queue_stats[] = {
FM10K_QUEUE_STAT("packets", stats.packets), FM10K_QUEUE_STAT("%s_queue_%u_packets", stats.packets),
FM10K_QUEUE_STAT("bytes", stats.bytes), FM10K_QUEUE_STAT("%s_queue_%u_bytes", stats.bytes),
}; };
#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats) #define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
...@@ -131,49 +135,44 @@ enum { ...@@ -131,49 +135,44 @@ enum {
static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = { static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
}; };
static void fm10k_add_stat_strings(u8 **p, const char *prefix, static void __fm10k_add_stat_strings(u8 **p, const struct fm10k_stats stats[],
const struct fm10k_stats stats[], const unsigned int size, ...)
const unsigned int size)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
snprintf(*p, ETH_GSTRING_LEN, "%s%s", va_list args;
prefix, stats[i].stat_string);
va_start(args, size);
vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
*p += ETH_GSTRING_LEN; *p += ETH_GSTRING_LEN;
va_end(args);
} }
} }
#define fm10k_add_stat_strings(p, stats, ...) \
__fm10k_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
static void fm10k_get_stat_strings(struct net_device *dev, u8 *data) static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
{ {
struct fm10k_intfc *interface = netdev_priv(dev); struct fm10k_intfc *interface = netdev_priv(dev);
unsigned int i; unsigned int i;
fm10k_add_stat_strings(&data, "", fm10k_gstrings_net_stats, fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats);
FM10K_NETDEV_STATS_LEN);
fm10k_add_stat_strings(&data, "", fm10k_gstrings_global_stats, fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats);
FM10K_GLOBAL_STATS_LEN);
fm10k_add_stat_strings(&data, "", fm10k_gstrings_mbx_stats, fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats);
FM10K_MBX_STATS_LEN);
if (interface->hw.mac.type != fm10k_mac_vf) if (interface->hw.mac.type != fm10k_mac_vf)
fm10k_add_stat_strings(&data, "", fm10k_gstrings_pf_stats, fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats);
FM10K_PF_STATS_LEN);
for (i = 0; i < interface->hw.mac.max_queues; i++) { for (i = 0; i < interface->hw.mac.max_queues; i++) {
char prefix[ETH_GSTRING_LEN]; fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
"tx", i);
snprintf(prefix, ETH_GSTRING_LEN, "tx_queue_%u_", i);
fm10k_add_stat_strings(&data, prefix,
fm10k_gstrings_queue_stats,
FM10K_QUEUE_STATS_LEN);
snprintf(prefix, ETH_GSTRING_LEN, "rx_queue_%u_", i); fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
fm10k_add_stat_strings(&data, prefix, "rx", i);
fm10k_gstrings_queue_stats,
FM10K_QUEUE_STATS_LEN);
} }
} }
...@@ -218,9 +217,9 @@ static int fm10k_get_sset_count(struct net_device *dev, int sset) ...@@ -218,9 +217,9 @@ static int fm10k_get_sset_count(struct net_device *dev, int sset)
} }
} }
static void fm10k_add_ethtool_stats(u64 **data, void *pointer, static void __fm10k_add_ethtool_stats(u64 **data, void *pointer,
const struct fm10k_stats stats[], const struct fm10k_stats stats[],
const unsigned int size) const unsigned int size)
{ {
unsigned int i; unsigned int i;
char *p; char *p;
...@@ -249,11 +248,16 @@ static void fm10k_add_ethtool_stats(u64 **data, void *pointer, ...@@ -249,11 +248,16 @@ static void fm10k_add_ethtool_stats(u64 **data, void *pointer,
*((*data)++) = *(u8 *)p; *((*data)++) = *(u8 *)p;
break; break;
default: default:
WARN_ONCE(1, "unexpected stat size for %s",
stats[i].stat_string);
*((*data)++) = 0; *((*data)++) = 0;
} }
} }
} }
#define fm10k_add_ethtool_stats(data, pointer, stats) \
__fm10k_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
static void fm10k_get_ethtool_stats(struct net_device *netdev, static void fm10k_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats __always_unused *stats, struct ethtool_stats __always_unused *stats,
u64 *data) u64 *data)
...@@ -264,20 +268,16 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev, ...@@ -264,20 +268,16 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
fm10k_update_stats(interface); fm10k_update_stats(interface);
fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats, fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats);
FM10K_NETDEV_STATS_LEN);
fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats, fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats);
FM10K_GLOBAL_STATS_LEN);
fm10k_add_ethtool_stats(&data, &interface->hw.mbx, fm10k_add_ethtool_stats(&data, &interface->hw.mbx,
fm10k_gstrings_mbx_stats, fm10k_gstrings_mbx_stats);
FM10K_MBX_STATS_LEN);
if (interface->hw.mac.type != fm10k_mac_vf) { if (interface->hw.mac.type != fm10k_mac_vf) {
fm10k_add_ethtool_stats(&data, interface, fm10k_add_ethtool_stats(&data, interface,
fm10k_gstrings_pf_stats, fm10k_gstrings_pf_stats);
FM10K_PF_STATS_LEN);
} }
for (i = 0; i < interface->hw.mac.max_queues; i++) { for (i = 0; i < interface->hw.mac.max_queues; i++) {
...@@ -285,13 +285,11 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev, ...@@ -285,13 +285,11 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
ring = interface->tx_ring[i]; ring = interface->tx_ring[i];
fm10k_add_ethtool_stats(&data, ring, fm10k_add_ethtool_stats(&data, ring,
fm10k_gstrings_queue_stats, fm10k_gstrings_queue_stats);
FM10K_QUEUE_STATS_LEN);
ring = interface->rx_ring[i]; ring = interface->rx_ring[i];
fm10k_add_ethtool_stats(&data, ring, fm10k_add_ethtool_stats(&data, ring,
fm10k_gstrings_queue_stats, fm10k_gstrings_queue_stats);
FM10K_QUEUE_STATS_LEN);
} }
} }
......
...@@ -907,7 +907,9 @@ static int fm10k_mc_vlan_unsync(struct net_device *netdev, ...@@ -907,7 +907,9 @@ static int fm10k_mc_vlan_unsync(struct net_device *netdev,
static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set) static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
{ {
struct fm10k_intfc *interface = netdev_priv(netdev); struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_l2_accel *l2_accel = interface->l2_accel;
struct fm10k_hw *hw = &interface->hw; struct fm10k_hw *hw = &interface->hw;
u16 glort;
s32 err; s32 err;
int i; int i;
...@@ -975,6 +977,22 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set) ...@@ -975,6 +977,22 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
if (err) if (err)
goto err_out; goto err_out;
/* Update L2 accelerated macvlan addresses */
if (l2_accel) {
for (i = 0; i < l2_accel->size; i++) {
struct net_device *sdev = l2_accel->macvlan[i];
if (!sdev)
continue;
glort = l2_accel->dglort + 1 + i;
fm10k_queue_mac_request(interface, glort,
sdev->dev_addr,
vid, set);
}
}
/* set VLAN ID prior to syncing/unsyncing the VLAN */ /* set VLAN ID prior to syncing/unsyncing the VLAN */
interface->vid = vid + (set ? VLAN_N_VID : 0); interface->vid = vid + (set ? VLAN_N_VID : 0);
...@@ -1214,6 +1232,22 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface) ...@@ -1214,6 +1232,22 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
fm10k_queue_mac_request(interface, glort, fm10k_queue_mac_request(interface, glort,
hw->mac.addr, vid, true); hw->mac.addr, vid, true);
/* synchronize macvlan addresses */
if (l2_accel) {
for (i = 0; i < l2_accel->size; i++) {
struct net_device *sdev = l2_accel->macvlan[i];
if (!sdev)
continue;
glort = l2_accel->dglort + 1 + i;
fm10k_queue_mac_request(interface, glort,
sdev->dev_addr,
vid, true);
}
}
} }
/* update xcast mode before synchronizing addresses if host's mailbox /* update xcast mode before synchronizing addresses if host's mailbox
...@@ -1430,7 +1464,7 @@ static void *fm10k_dfwd_add_station(struct net_device *dev, ...@@ -1430,7 +1464,7 @@ static void *fm10k_dfwd_add_station(struct net_device *dev,
struct fm10k_dglort_cfg dglort = { 0 }; struct fm10k_dglort_cfg dglort = { 0 };
struct fm10k_hw *hw = &interface->hw; struct fm10k_hw *hw = &interface->hw;
int size = 0, i; int size = 0, i;
u16 glort; u16 vid, glort;
/* The hardware supported by fm10k only filters on the destination MAC /* The hardware supported by fm10k only filters on the destination MAC
* address. In order to avoid issues we only support offloading modes * address. In order to avoid issues we only support offloading modes
...@@ -1503,12 +1537,18 @@ static void *fm10k_dfwd_add_station(struct net_device *dev, ...@@ -1503,12 +1537,18 @@ static void *fm10k_dfwd_add_station(struct net_device *dev,
glort = l2_accel->dglort + 1 + i; glort = l2_accel->dglort + 1 + i;
if (fm10k_host_mbx_ready(interface)) { if (fm10k_host_mbx_ready(interface))
hw->mac.ops.update_xcast_mode(hw, glort, hw->mac.ops.update_xcast_mode(hw, glort,
FM10K_XCAST_MODE_NONE); FM10K_XCAST_MODE_NONE);
fm10k_queue_mac_request(interface, glort, sdev->dev_addr,
hw->mac.default_vid, true);
for (vid = fm10k_find_next_vlan(interface, 0);
vid < VLAN_N_VID;
vid = fm10k_find_next_vlan(interface, vid))
fm10k_queue_mac_request(interface, glort, sdev->dev_addr, fm10k_queue_mac_request(interface, glort, sdev->dev_addr,
hw->mac.default_vid, true); vid, true);
}
fm10k_mbx_unlock(interface); fm10k_mbx_unlock(interface);
...@@ -1522,8 +1562,8 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv) ...@@ -1522,8 +1562,8 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv)
struct fm10k_dglort_cfg dglort = { 0 }; struct fm10k_dglort_cfg dglort = { 0 };
struct fm10k_hw *hw = &interface->hw; struct fm10k_hw *hw = &interface->hw;
struct net_device *sdev = priv; struct net_device *sdev = priv;
u16 vid, glort;
int i; int i;
u16 glort;
if (!l2_accel) if (!l2_accel)
return; return;
...@@ -1543,12 +1583,18 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv) ...@@ -1543,12 +1583,18 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv)
glort = l2_accel->dglort + 1 + i; glort = l2_accel->dglort + 1 + i;
if (fm10k_host_mbx_ready(interface)) { if (fm10k_host_mbx_ready(interface))
hw->mac.ops.update_xcast_mode(hw, glort, hw->mac.ops.update_xcast_mode(hw, glort,
FM10K_XCAST_MODE_NONE); FM10K_XCAST_MODE_NONE);
fm10k_queue_mac_request(interface, glort, sdev->dev_addr,
hw->mac.default_vid, false);
for (vid = fm10k_find_next_vlan(interface, 0);
vid < VLAN_N_VID;
vid = fm10k_find_next_vlan(interface, vid))
fm10k_queue_mac_request(interface, glort, sdev->dev_addr, fm10k_queue_mac_request(interface, glort, sdev->dev_addr,
hw->mac.default_vid, false); vid, false);
}
fm10k_mbx_unlock(interface); fm10k_mbx_unlock(interface);
......
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