diff options
author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2012-11-25 18:10:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-26 17:22:12 -0500 |
commit | 62a2ab935c8d0f8643d02d3696abc401b5da6206 (patch) | |
tree | 621848d4f395f224faa16e576d5f5b93a63f01a2 /drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |
parent | 9125cdd1be1199588f71c99e76e32bcda0b7d847 (diff) |
stmmac: add Rx watchdog support to mitigate the DMA irqs
GMAC devices newer than databook 3.40 has an embedded timer
that can be used for mitigating the number of interrupts.
So this patch adds this optimizations.
At any rate, the Rx watchdog can be disable (on bugged HW) by
passing from the platform the riwt_off field.
In this implementation the rx timer stored in the Reg9 is fixed
to the max value. This will be tuned by using ethtool.
V2: added a platform parameter to force to disable the rx-watchdog
for example on new core where it is bugged.
V3: do not disable NAPI when Rx watchdog is used.
V4: a new extra statistic field has been added to show the early
receive status in the interrupt handler.
This patch also adds an extra check to avoid to call
napi_schedule when the DMA_INTR_ENA_RIE bit is disabled in the
Interrupt Mask register.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d9d68649bdaa..542edbcd92c7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -603,6 +603,8 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
603 | priv->dirty_tx = 0; | 603 | priv->dirty_tx = 0; |
604 | priv->cur_tx = 0; | 604 | priv->cur_tx = 0; |
605 | 605 | ||
606 | if (priv->use_riwt) | ||
607 | dis_ic = 1; | ||
606 | /* Clear the Rx/Tx descriptors */ | 608 | /* Clear the Rx/Tx descriptors */ |
607 | priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); | 609 | priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); |
608 | priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); | 610 | priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); |
@@ -1106,6 +1108,11 @@ static int stmmac_open(struct net_device *dev) | |||
1106 | 1108 | ||
1107 | stmmac_init_tx_coalesce(priv); | 1109 | stmmac_init_tx_coalesce(priv); |
1108 | 1110 | ||
1111 | if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { | ||
1112 | priv->rx_riwt = MAX_DMA_RIWT; | ||
1113 | priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); | ||
1114 | } | ||
1115 | |||
1109 | napi_enable(&priv->napi); | 1116 | napi_enable(&priv->napi); |
1110 | netif_start_queue(dev); | 1117 | netif_start_queue(dev); |
1111 | 1118 | ||
@@ -1423,14 +1430,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) | |||
1423 | #endif | 1430 | #endif |
1424 | skb->protocol = eth_type_trans(skb, priv->dev); | 1431 | skb->protocol = eth_type_trans(skb, priv->dev); |
1425 | 1432 | ||
1426 | if (unlikely(!priv->plat->rx_coe)) { | 1433 | if (unlikely(!priv->plat->rx_coe)) |
1427 | /* No RX COE for old mac10/100 devices */ | ||
1428 | skb_checksum_none_assert(skb); | 1434 | skb_checksum_none_assert(skb); |
1429 | netif_receive_skb(skb); | 1435 | else |
1430 | } else { | ||
1431 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1436 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1432 | napi_gro_receive(&priv->napi, skb); | 1437 | |
1433 | } | 1438 | napi_gro_receive(&priv->napi, skb); |
1434 | 1439 | ||
1435 | priv->dev->stats.rx_packets++; | 1440 | priv->dev->stats.rx_packets++; |
1436 | priv->dev->stats.rx_bytes += frame_len; | 1441 | priv->dev->stats.rx_bytes += frame_len; |
@@ -2001,6 +2006,16 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, | |||
2001 | if (flow_ctrl) | 2006 | if (flow_ctrl) |
2002 | priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ | 2007 | priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ |
2003 | 2008 | ||
2009 | /* Rx Watchdog is available in the COREs newer than the 3.40. | ||
2010 | * In some case, for example on bugged HW this feature | ||
2011 | * has to be disable and this can be done by passing the | ||
2012 | * riwt_off field from the platform. | ||
2013 | */ | ||
2014 | if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { | ||
2015 | priv->use_riwt = 1; | ||
2016 | pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); | ||
2017 | } | ||
2018 | |||
2004 | netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); | 2019 | netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); |
2005 | 2020 | ||
2006 | spin_lock_init(&priv->lock); | 2021 | spin_lock_init(&priv->lock); |
@@ -2092,6 +2107,9 @@ int stmmac_suspend(struct net_device *ndev) | |||
2092 | netif_device_detach(ndev); | 2107 | netif_device_detach(ndev); |
2093 | netif_stop_queue(ndev); | 2108 | netif_stop_queue(ndev); |
2094 | 2109 | ||
2110 | if (priv->use_riwt) | ||
2111 | dis_ic = 1; | ||
2112 | |||
2095 | napi_disable(&priv->napi); | 2113 | napi_disable(&priv->napi); |
2096 | 2114 | ||
2097 | /* Stop TX/RX DMA */ | 2115 | /* Stop TX/RX DMA */ |