aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2012-11-25 18:10:44 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-26 17:22:12 -0500
commit48f44da4542d8f91d8b0603e20929b184dc2aa4e (patch)
treea0789a70089bea5031f75b67a49cf1c937441ca5
parent62a2ab935c8d0f8643d02d3696abc401b5da6206 (diff)
stmmac: get/set coalesce parameters via ethtool
This patch is to get/set the tx/rx coalesce parameters via ethtool interface. Tests have been done on several platform with different GMAC chips w/o and w/ RX watchdog feature. V2: reject coalesce settings that are not supported. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 7f7ccd217e4..1372ce210b5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -524,6 +524,87 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
524 return phy_ethtool_set_eee(priv->phydev, edata); 524 return phy_ethtool_set_eee(priv->phydev, edata);
525} 525}
526 526
527static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)
528{
529 unsigned long clk = clk_get_rate(priv->stmmac_clk);
530
531 if (!clk)
532 return 0;
533
534 return (usec * (clk / 1000000)) / 256;
535}
536
537static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv)
538{
539 unsigned long clk = clk_get_rate(priv->stmmac_clk);
540
541 if (!clk)
542 return 0;
543
544 return (riwt * 256) / (clk / 1000000);
545}
546
547static int stmmac_get_coalesce(struct net_device *dev,
548 struct ethtool_coalesce *ec)
549{
550 struct stmmac_priv *priv = netdev_priv(dev);
551
552 ec->tx_coalesce_usecs = priv->tx_coal_timer;
553 ec->tx_max_coalesced_frames = priv->tx_coal_frames;
554
555 if (priv->use_riwt)
556 ec->rx_coalesce_usecs = stmmac_riwt2usec(priv->rx_riwt, priv);
557
558 return 0;
559}
560
561static int stmmac_set_coalesce(struct net_device *dev,
562 struct ethtool_coalesce *ec)
563{
564 struct stmmac_priv *priv = netdev_priv(dev);
565 unsigned int rx_riwt;
566
567 /* Check not supported parameters */
568 if ((ec->rx_max_coalesced_frames) || (ec->rx_coalesce_usecs_irq) ||
569 (ec->rx_max_coalesced_frames_irq) || (ec->tx_coalesce_usecs_irq) ||
570 (ec->use_adaptive_rx_coalesce) || (ec->use_adaptive_tx_coalesce) ||
571 (ec->pkt_rate_low) || (ec->rx_coalesce_usecs_low) ||
572 (ec->rx_max_coalesced_frames_low) || (ec->tx_coalesce_usecs_high) ||
573 (ec->tx_max_coalesced_frames_low) || (ec->pkt_rate_high) ||
574 (ec->tx_coalesce_usecs_low) || (ec->rx_coalesce_usecs_high) ||
575 (ec->rx_max_coalesced_frames_high) ||
576 (ec->tx_max_coalesced_frames_irq) ||
577 (ec->stats_block_coalesce_usecs) ||
578 (ec->tx_max_coalesced_frames_high) || (ec->rate_sample_interval))
579 return -EOPNOTSUPP;
580
581 if (ec->rx_coalesce_usecs == 0)
582 return -EINVAL;
583
584 if ((ec->tx_coalesce_usecs == 0) &&
585 (ec->tx_max_coalesced_frames == 0))
586 return -EINVAL;
587
588 if ((ec->tx_coalesce_usecs > STMMAC_COAL_TX_TIMER) ||
589 (ec->tx_max_coalesced_frames > STMMAC_TX_MAX_FRAMES))
590 return -EINVAL;
591
592 rx_riwt = stmmac_usec2riwt(ec->rx_coalesce_usecs, priv);
593
594 if ((rx_riwt > MAX_DMA_RIWT) || (rx_riwt < MIN_DMA_RIWT))
595 return -EINVAL;
596 else if (!priv->use_riwt)
597 return -EOPNOTSUPP;
598
599 /* Only copy relevant parameters, ignore all others. */
600 priv->tx_coal_frames = ec->tx_max_coalesced_frames;
601 priv->tx_coal_timer = ec->tx_coalesce_usecs;
602 priv->rx_riwt = rx_riwt;
603 priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt);
604
605 return 0;
606}
607
527static const struct ethtool_ops stmmac_ethtool_ops = { 608static const struct ethtool_ops stmmac_ethtool_ops = {
528 .begin = stmmac_check_if_running, 609 .begin = stmmac_check_if_running,
529 .get_drvinfo = stmmac_ethtool_getdrvinfo, 610 .get_drvinfo = stmmac_ethtool_getdrvinfo,
@@ -544,6 +625,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
544 .set_eee = stmmac_ethtool_op_set_eee, 625 .set_eee = stmmac_ethtool_op_set_eee,
545 .get_sset_count = stmmac_get_sset_count, 626 .get_sset_count = stmmac_get_sset_count,
546 .get_ts_info = ethtool_op_get_ts_info, 627 .get_ts_info = ethtool_op_get_ts_info,
628 .get_coalesce = stmmac_get_coalesce,
629 .set_coalesce = stmmac_set_coalesce,
547}; 630};
548 631
549void stmmac_set_ethtool_ops(struct net_device *netdev) 632void stmmac_set_ethtool_ops(struct net_device *netdev)