Skip to content

Commit

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

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-09-22

This series contains updates to e1000, e1000e, igbvf, ixgbe, ixgbevf and
fm10k.

Jacob provides several updates for fm10k, which cleans up comments and
most notably a fix for a corner case issue with the PF/VF mailbox code.
The issue being fm10k_mbx_reset_work clears various states about the
mailbox, but does not clear the Tx FIFO head/tail pointers.  We also
are not able to simply clear these pointers, as we would drop
untransmitted messages without error.  Also adds support for extra debug
statistics, which provides the ability to see what the PF thinks the
VF mailboxes look like.

Don adds support for SFP+ in X550 and support for SCTP flow director
filters SCTP mask.

Francois Romieu dusts off the e1000 driver and removes some dead calls
to e1000_init_eeprom_params().

Toshiaki Makita provides three patches to enable TSO for stacked VLAN's
on e1000e, igbvf and ixgbevf.

Mark provides the first of several ixgbe updates.  First updates the
driver to accept SFP not present error for all devices, since an SFP
can still be inserted.  Adds support for SFP insertion interrupt on
X550EM devices with SPFs.  Adds I2C combined operations on X550EM
(not X550) devices.  Moved the setting of lan_id to before any I2C
eeprom access.  Lastly, set the bit bang mode in the hardware when
performing bit banding I2C operations on X550.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Sep 23, 2015
2 parents 16cfbae + 25b1029 commit 6015a6c
Show file tree
Hide file tree
Showing 17 changed files with 568 additions and 91 deletions.
8 changes: 0 additions & 8 deletions drivers/net/ethernet/intel/e1000/e1000_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -3900,10 +3900,6 @@ static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
return E1000_SUCCESS;
}

/* If eeprom is not yet detected, do so now */
if (eeprom->word_size == 0)
e1000_init_eeprom_params(hw);

/* A check for invalid values: offset too large, too many words, and
* not enough words.
*/
Expand Down Expand Up @@ -4074,10 +4070,6 @@ static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
return E1000_SUCCESS;
}

/* If eeprom is not yet detected, do so now */
if (eeprom->word_size == 0)
e1000_init_eeprom_params(hw);

/* A check for invalid values: offset too large, too many words, and
* not enough words.
*/
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6952,6 +6952,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
#endif
.ndo_set_features = e1000_set_features,
.ndo_fix_features = e1000_fix_features,
.ndo_features_check = passthru_features_check,
};

/**
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/ethernet/intel/fm10k/fm10k.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,19 @@ struct fm10k_tx_queue_stats {
u64 csum_err;
u64 tx_busy;
u64 tx_done_old;
u64 csum_good;
};

struct fm10k_rx_queue_stats {
u64 alloc_failed;
u64 csum_err;
u64 errors;
u64 csum_good;
u64 switch_errors;
u64 drops;
u64 pp_errors;
u64 link_errors;
u64 length_errors;
};

struct fm10k_ring {
Expand Down Expand Up @@ -251,6 +258,7 @@ struct fm10k_intfc {
#define FM10K_FLAG_RSS_FIELD_IPV6_UDP (u32)(1 << 2)
#define FM10K_FLAG_RX_TS_ENABLED (u32)(1 << 3)
#define FM10K_FLAG_SWPRI_CONFIG (u32)(1 << 4)
#define FM10K_FLAG_DEBUG_STATS (u32)(1 << 5)
int xcast_mode;

/* Tx fast path data */
Expand All @@ -277,6 +285,17 @@ struct fm10k_intfc {
u64 rx_drops_nic;
u64 rx_overrun_pf;
u64 rx_overrun_vf;

/* Debug Statistics */
u64 hw_sm_mbx_full;
u64 hw_csum_tx_good;
u64 hw_csum_rx_good;
u64 rx_switch_errors;
u64 rx_drops;
u64 rx_pp_errors;
u64 rx_link_errors;
u64 rx_length_errors;

u32 tx_timeout_count;

/* RX */
Expand Down
216 changes: 181 additions & 35 deletions drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,22 @@ static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
FM10K_STAT("mac_rules_used", hw.swapi.mac.used),
FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail),

FM10K_STAT("mbx_tx_busy", hw.mbx.tx_busy),
FM10K_STAT("mbx_tx_oversized", hw.mbx.tx_dropped),
FM10K_STAT("mbx_tx_messages", hw.mbx.tx_messages),
FM10K_STAT("mbx_tx_dwords", hw.mbx.tx_dwords),
FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages),
FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords),
FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err),

FM10K_STAT("tx_hang_count", tx_timeout_count),

FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
};

static const struct fm10k_stats fm10k_gstrings_debug_stats[] = {
FM10K_STAT("hw_sm_mbx_full", hw_sm_mbx_full),
FM10K_STAT("hw_csum_tx_good", hw_csum_tx_good),
FM10K_STAT("hw_csum_rx_good", hw_csum_rx_good),
FM10K_STAT("rx_switch_errors", rx_switch_errors),
FM10K_STAT("rx_drops", rx_drops),
FM10K_STAT("rx_pp_errors", rx_pp_errors),
FM10K_STAT("rx_link_errors", rx_link_errors),
FM10K_STAT("rx_length_errors", rx_length_errors),
};

static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
FM10K_STAT("timeout", stats.timeout.count),
FM10K_STAT("ur", stats.ur.count),
Expand All @@ -100,14 +103,33 @@ static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
};

#define FM10K_MBX_STAT(_name, _stat) { \
.stat_string = _name, \
.sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \
.stat_offset = offsetof(struct fm10k_mbx_info, _stat) \
}

static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
FM10K_MBX_STAT("mbx_tx_oversized", tx_dropped),
FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
};

#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
#define FM10K_DEBUG_STATS_LEN ARRAY_SIZE(fm10k_gstrings_debug_stats)
#define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
#define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)

#define FM10K_QUEUE_STATS_LEN(_n) \
( (_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))

#define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
FM10K_NETDEV_STATS_LEN)
FM10K_NETDEV_STATS_LEN + \
FM10K_MBX_STATS_LEN)

static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
"Mailbox test (on/offline)"
Expand All @@ -120,54 +142,105 @@ enum fm10k_self_test_types {
FM10K_TEST_MAX = FM10K_TEST_LEN
};

static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
enum {
FM10K_PRV_FLAG_DEBUG_STATS,
FM10K_PRV_FLAG_LEN,
};

static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
"debug-statistics",
};

static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
{
struct fm10k_intfc *interface = netdev_priv(dev);
struct fm10k_iov_data *iov_data = interface->iov_data;
char *p = (char *)data;
unsigned int i;
unsigned int j;

switch (stringset) {
case ETH_SS_TEST:
memcpy(data, *fm10k_gstrings_test,
FM10K_TEST_LEN * ETH_GSTRING_LEN);
break;
case ETH_SS_STATS:
for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}

for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_global_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}

if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
for (i = 0; i < FM10K_DEBUG_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_debug_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_global_stats[i].stat_string,
}

for (i = 0; i < FM10K_MBX_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_mbx_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}

if (interface->hw.mac.type != fm10k_mac_vf) {
for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
}

if (interface->hw.mac.type != fm10k_mac_vf) {
for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
ETH_GSTRING_LEN);
if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
for (i = 0; i < iov_data->num_vfs; i++) {
for (j = 0; j < FM10K_MBX_STATS_LEN; j++) {
snprintf(p,
ETH_GSTRING_LEN,
"vf_%u_%s", i,
fm10k_gstrings_mbx_stats[j].stat_string);
p += ETH_GSTRING_LEN;
}
}
}

for (i = 0; i < interface->hw.mac.max_queues; i++) {
sprintf(p, "tx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "tx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
for (i = 0; i < interface->hw.mac.max_queues; i++) {
sprintf(p, "tx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "tx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
}

static void fm10k_get_strings(struct net_device *dev,
u32 stringset, u8 *data)
{
char *p = (char *)data;

switch (stringset) {
case ETH_SS_TEST:
memcpy(data, *fm10k_gstrings_test,
FM10K_TEST_LEN * ETH_GSTRING_LEN);
break;
case ETH_SS_STATS:
fm10k_get_stat_strings(dev, data);
break;
case ETH_SS_PRIV_FLAGS:
memcpy(p, fm10k_prv_flags,
FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
break;
}
}

static int fm10k_get_sset_count(struct net_device *dev, int sset)
{
struct fm10k_intfc *interface = netdev_priv(dev);
struct fm10k_iov_data *iov_data = interface->iov_data;
struct fm10k_hw *hw = &interface->hw;
int stats_len = FM10K_STATIC_STATS_LEN;

Expand All @@ -180,7 +253,16 @@ static int fm10k_get_sset_count(struct net_device *dev, int sset)
if (hw->mac.type != fm10k_mac_vf)
stats_len += FM10K_PF_STATS_LEN;

if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
stats_len += FM10K_DEBUG_STATS_LEN;

if (iov_data)
stats_len += FM10K_MBX_STATS_LEN * iov_data->num_vfs;
}

return stats_len;
case ETH_SS_PRIV_FLAGS:
return FM10K_PRV_FLAG_LEN;
default:
return -EOPNOTSUPP;
}
Expand All @@ -192,6 +274,7 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
{
const int stat_count = sizeof(struct fm10k_queue_stats) / sizeof(u64);
struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_iov_data *iov_data = interface->iov_data;
struct net_device_stats *net_stats = &netdev->stats;
char *p;
int i, j;
Expand All @@ -211,13 +294,47 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}

if (interface->hw.mac.type != fm10k_mac_vf)
if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
for (i = 0; i < FM10K_DEBUG_STATS_LEN; i++) {
p = (char *)interface + fm10k_gstrings_debug_stats[i].stat_offset;
*(data++) = (fm10k_gstrings_debug_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
}

for (i = 0; i < FM10K_MBX_STATS_LEN; i++) {
p = (char *)&interface->hw.mbx + fm10k_gstrings_mbx_stats[i].stat_offset;
*(data++) = (fm10k_gstrings_mbx_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}

if (interface->hw.mac.type != fm10k_mac_vf) {
for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
p = (char *)interface +
fm10k_gstrings_pf_stats[i].stat_offset;
*(data++) = (fm10k_gstrings_pf_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
}

if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
for (i = 0; i < iov_data->num_vfs; i++) {
struct fm10k_vf_info *vf_info;
vf_info = &iov_data->vf_info[i];

/* skip stats if we don't have a vf info */
if (!vf_info) {
data += FM10K_MBX_STATS_LEN;
continue;
}

for (j = 0; j < FM10K_MBX_STATS_LEN; j++) {
p = (char *)&vf_info->mbx + fm10k_gstrings_mbx_stats[j].stat_offset;
*(data++) = (fm10k_gstrings_mbx_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
}
}

for (i = 0; i < interface->hw.mac.max_queues; i++) {
struct fm10k_ring *ring;
Expand Down Expand Up @@ -881,6 +998,33 @@ static void fm10k_self_test(struct net_device *dev,
eth_test->flags |= ETH_TEST_FL_FAILED;
}

static u32 fm10k_get_priv_flags(struct net_device *netdev)
{
struct fm10k_intfc *interface = netdev_priv(netdev);
u32 priv_flags = 0;

if (interface->flags & FM10K_FLAG_DEBUG_STATS)
priv_flags |= 1 << FM10K_PRV_FLAG_DEBUG_STATS;

return priv_flags;
}

static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
{
struct fm10k_intfc *interface = netdev_priv(netdev);

if (priv_flags >= (1 << FM10K_PRV_FLAG_LEN))
return -EINVAL;

if (priv_flags & (1 << FM10K_PRV_FLAG_DEBUG_STATS))
interface->flags |= FM10K_FLAG_DEBUG_STATS;
else
interface->flags &= ~FM10K_FLAG_DEBUG_STATS;

return 0;
}


static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
{
return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
Expand Down Expand Up @@ -1094,6 +1238,8 @@ static const struct ethtool_ops fm10k_ethtool_ops = {
.get_regs = fm10k_get_regs,
.get_regs_len = fm10k_get_regs_len,
.self_test = fm10k_self_test,
.get_priv_flags = fm10k_get_priv_flags,
.set_priv_flags = fm10k_set_priv_flags,
.get_rxfh_indir_size = fm10k_get_reta_size,
.get_rxfh_key_size = fm10k_get_rssrk_size,
.get_rxfh = fm10k_get_rssh,
Expand Down
Loading

0 comments on commit 6015a6c

Please sign in to comment.