summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index f628411ae4ae..42d27b97dd1d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -212,6 +212,8 @@ static const struct stmmac_stats stmmac_mmc[] = {
STMMAC_MMC_STAT(mmc_tx_excessdef),
STMMAC_MMC_STAT(mmc_tx_pause_frame),
STMMAC_MMC_STAT(mmc_tx_vlan_frame_g),
+ STMMAC_MMC_STAT(mmc_tx_lpi_usec),
+ STMMAC_MMC_STAT(mmc_tx_lpi_tran),
STMMAC_MMC_STAT(mmc_rx_framecount_gb),
STMMAC_MMC_STAT(mmc_rx_octetcount_gb),
STMMAC_MMC_STAT(mmc_rx_octetcount_g),
@@ -236,6 +238,11 @@ static const struct stmmac_stats stmmac_mmc[] = {
STMMAC_MMC_STAT(mmc_rx_fifo_overflow),
STMMAC_MMC_STAT(mmc_rx_vlan_frames_gb),
STMMAC_MMC_STAT(mmc_rx_watchdog_error),
+ STMMAC_MMC_STAT(mmc_rx_lpi_usec),
+ STMMAC_MMC_STAT(mmc_rx_lpi_tran),
+ STMMAC_MMC_STAT(mmc_rx_discard_frames_gb),
+ STMMAC_MMC_STAT(mmc_rx_discard_octets_gb),
+ STMMAC_MMC_STAT(mmc_rx_align_err_frames),
STMMAC_MMC_STAT(mmc_rx_ipc_intr_mask),
STMMAC_MMC_STAT(mmc_rx_ipc_intr),
STMMAC_MMC_STAT(mmc_rx_ipv4_gd),
@@ -266,8 +273,11 @@ static const struct stmmac_stats stmmac_mmc[] = {
STMMAC_MMC_STAT(mmc_rx_tcp_err_octets),
STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),
STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),
+ STMMAC_MMC_STAT(mmc_sgf_pass_fragment_cntr),
+ STMMAC_MMC_STAT(mmc_sgf_fail_fragment_cntr),
STMMAC_MMC_STAT(mmc_tx_fpe_fragment_cntr),
STMMAC_MMC_STAT(mmc_tx_hold_req_cntr),
+ STMMAC_MMC_STAT(mmc_tx_gate_overrun_cntr),
STMMAC_MMC_STAT(mmc_rx_packet_assembly_err_cntr),
STMMAC_MMC_STAT(mmc_rx_packet_smd_err_cntr),
STMMAC_MMC_STAT(mmc_rx_packet_assembly_ok_cntr),
@@ -311,8 +321,9 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
{
struct stmmac_priv *priv = netdev_priv(dev);
- if (priv->hw->pcs & STMMAC_PCS_RGMII ||
- priv->hw->pcs & STMMAC_PCS_SGMII) {
+ if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
+ (priv->hw->pcs & STMMAC_PCS_RGMII ||
+ priv->hw->pcs & STMMAC_PCS_SGMII)) {
struct rgmii_adv adv;
u32 supported, advertising, lp_advertising;
@@ -397,8 +408,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
{
struct stmmac_priv *priv = netdev_priv(dev);
- if (priv->hw->pcs & STMMAC_PCS_RGMII ||
- priv->hw->pcs & STMMAC_PCS_SGMII) {
+ if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
+ (priv->hw->pcs & STMMAC_PCS_RGMII ||
+ priv->hw->pcs & STMMAC_PCS_SGMII)) {
/* Only support ANE */
if (cmd->base.autoneg != AUTONEG_ENABLE)
return -EINVAL;
@@ -543,15 +555,12 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
u32 rx_cnt = priv->plat->rx_queues_to_use;
unsigned int start;
int q, stat;
- u64 *pos;
char *p;
- pos = data;
for (q = 0; q < tx_cnt; q++) {
struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
struct stmmac_txq_stats snapshot;
- data = pos;
do {
start = u64_stats_fetch_begin(&txq_stats->syncp);
snapshot = *txq_stats;
@@ -559,17 +568,15 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
- *data++ += (*(u64 *)p);
+ *data++ = (*(u64 *)p);
p += sizeof(u64);
}
}
- pos = data;
for (q = 0; q < rx_cnt; q++) {
struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
struct stmmac_rxq_stats snapshot;
- data = pos;
do {
start = u64_stats_fetch_begin(&rxq_stats->syncp);
snapshot = *rxq_stats;
@@ -577,7 +584,7 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
- *data++ += (*(u64 *)p);
+ *data++ = (*(u64 *)p);
p += sizeof(u64);
}
}
@@ -825,10 +832,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts) {
pr_info("stmmac: wakeup enable\n");
device_set_wakeup_enable(priv->device, 1);
- enable_irq_wake(priv->wol_irq);
+ /* Avoid unbalanced enable_irq_wake calls */
+ if (priv->wol_irq_disabled)
+ enable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = false;
} else {
device_set_wakeup_enable(priv->device, 0);
- disable_irq_wake(priv->wol_irq);
+ /* Avoid unbalanced disable_irq_wake calls */
+ if (!priv->wol_irq_disabled)
+ disable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = true;
}
mutex_lock(&priv->lock);
@@ -1077,41 +1090,42 @@ static u32 stmmac_get_rxfh_indir_size(struct net_device *dev)
return ARRAY_SIZE(priv->rss.table);
}
-static int stmmac_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
- u8 *hfunc)
+static int stmmac_get_rxfh(struct net_device *dev,
+ struct ethtool_rxfh_param *rxfh)
{
struct stmmac_priv *priv = netdev_priv(dev);
int i;
- if (indir) {
+ if (rxfh->indir) {
for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)
- indir[i] = priv->rss.table[i];
+ rxfh->indir[i] = priv->rss.table[i];
}
- if (key)
- memcpy(key, priv->rss.key, sizeof(priv->rss.key));
- if (hfunc)
- *hfunc = ETH_RSS_HASH_TOP;
+ if (rxfh->key)
+ memcpy(rxfh->key, priv->rss.key, sizeof(priv->rss.key));
+ rxfh->hfunc = ETH_RSS_HASH_TOP;
return 0;
}
-static int stmmac_set_rxfh(struct net_device *dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+static int stmmac_set_rxfh(struct net_device *dev,
+ struct ethtool_rxfh_param *rxfh,
+ struct netlink_ext_ack *extack)
{
struct stmmac_priv *priv = netdev_priv(dev);
int i;
- if ((hfunc != ETH_RSS_HASH_NO_CHANGE) && (hfunc != ETH_RSS_HASH_TOP))
+ if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
+ rxfh->hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
- if (indir) {
+ if (rxfh->indir) {
for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)
- priv->rss.table[i] = indir[i];
+ priv->rss.table[i] = rxfh->indir[i];
}
- if (key)
- memcpy(priv->rss.key, key, sizeof(priv->rss.key));
+ if (rxfh->key)
+ memcpy(priv->rss.key, rxfh->key, sizeof(priv->rss.key));
return stmmac_rss_configure(priv, priv->hw, &priv->rss,
priv->plat->rx_queues_to_use);