diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 70 |
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); |