aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDai Haruki <dai.haruki@freescale.com>2008-12-17 19:52:00 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-17 19:52:00 -0500
commit8c7396aebb68994c0519e438eecdf4d5fa9c7844 (patch)
tree9d4d71f7f5fb7a47348b7821526d85c3eacb6ff3
parentc50a5d9aedef5b0b289d07f6d73934d394e50b3f (diff)
gianfar: Merge Tx and Rx interrupt for scheduling clean up ring
No clean up function is executed in the interrupt context by this patch. Signed-off-by: Dai Haruki <dai.haruki@freescale.com> Acked-by: Andy Fleming <afleming@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/gianfar.c59
-rw-r--r--drivers/net/gianfar.h2
2 files changed, 19 insertions, 42 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 854f2ae3e56e..d243c9eea43a 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1604,29 +1604,19 @@ static int gfar_clean_tx_ring(struct net_device *dev)
1604 return howmany; 1604 return howmany;
1605} 1605}
1606 1606
1607/* Interrupt Handler for Transmit complete */ 1607static void gfar_schedule_cleanup(struct net_device *dev)
1608static irqreturn_t gfar_transmit(int irq, void *dev_id)
1609{ 1608{
1610 struct net_device *dev = (struct net_device *) dev_id;
1611 struct gfar_private *priv = netdev_priv(dev); 1609 struct gfar_private *priv = netdev_priv(dev);
1612 1610 if (netif_rx_schedule_prep(dev, &priv->napi)) {
1613 /* Clear IEVENT */ 1611 gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
1614 gfar_write(&priv->regs->ievent, IEVENT_TX_MASK); 1612 __netif_rx_schedule(dev, &priv->napi);
1615
1616 /* Lock priv */
1617 spin_lock(&priv->txlock);
1618
1619 gfar_clean_tx_ring(dev);
1620
1621 /* If we are coalescing the interrupts, reset the timer */
1622 /* Otherwise, clear it */
1623 if (likely(priv->txcoalescing)) {
1624 gfar_write(&priv->regs->txic, 0);
1625 gfar_write(&priv->regs->txic, priv->txic);
1626 } 1613 }
1614}
1627 1615
1628 spin_unlock(&priv->txlock); 1616/* Interrupt Handler for Transmit complete */
1629 1617static irqreturn_t gfar_transmit(int irq, void *dev_id)
1618{
1619 gfar_schedule_cleanup((struct net_device *)dev_id);
1630 return IRQ_HANDLED; 1620 return IRQ_HANDLED;
1631} 1621}
1632 1622
@@ -1713,28 +1703,7 @@ static inline void count_errors(unsigned short status, struct net_device *dev)
1713 1703
1714irqreturn_t gfar_receive(int irq, void *dev_id) 1704irqreturn_t gfar_receive(int irq, void *dev_id)
1715{ 1705{
1716 struct net_device *dev = (struct net_device *) dev_id; 1706 gfar_schedule_cleanup((struct net_device *)dev_id);
1717 struct gfar_private *priv = netdev_priv(dev);
1718 u32 tempval;
1719
1720 /* support NAPI */
1721 /* Clear IEVENT, so interrupts aren't called again
1722 * because of the packets that have already arrived */
1723 gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
1724
1725 if (netif_rx_schedule_prep(dev, &priv->napi)) {
1726 tempval = gfar_read(&priv->regs->imask);
1727 tempval &= IMASK_RTX_DISABLED;
1728 gfar_write(&priv->regs->imask, tempval);
1729
1730 __netif_rx_schedule(dev, &priv->napi);
1731 } else {
1732 if (netif_msg_rx_err(priv))
1733 printk(KERN_DEBUG "%s: receive called twice (%x)[%x]\n",
1734 dev->name, gfar_read(&priv->regs->ievent),
1735 gfar_read(&priv->regs->imask));
1736 }
1737
1738 return IRQ_HANDLED; 1707 return IRQ_HANDLED;
1739} 1708}
1740 1709
@@ -1877,6 +1846,10 @@ static int gfar_poll(struct napi_struct *napi, int budget)
1877 int howmany; 1846 int howmany;
1878 unsigned long flags; 1847 unsigned long flags;
1879 1848
1849 /* Clear IEVENT, so interrupts aren't called again
1850 * because of the packets that have already arrived */
1851 gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
1852
1880 /* If we fail to get the lock, don't bother with the TX BDs */ 1853 /* If we fail to get the lock, don't bother with the TX BDs */
1881 if (spin_trylock_irqsave(&priv->txlock, flags)) { 1854 if (spin_trylock_irqsave(&priv->txlock, flags)) {
1882 gfar_clean_tx_ring(dev); 1855 gfar_clean_tx_ring(dev);
@@ -1899,6 +1872,10 @@ static int gfar_poll(struct napi_struct *napi, int budget)
1899 gfar_write(&priv->regs->rxic, 0); 1872 gfar_write(&priv->regs->rxic, 0);
1900 gfar_write(&priv->regs->rxic, priv->rxic); 1873 gfar_write(&priv->regs->rxic, priv->rxic);
1901 } 1874 }
1875 if (likely(priv->txcoalescing)) {
1876 gfar_write(&priv->regs->txic, 0);
1877 gfar_write(&priv->regs->txic, priv->txic);
1878 }
1902 } 1879 }
1903 1880
1904 return howmany; 1881 return howmany;
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 06bac34c3b52..b1a83344acc7 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -251,7 +251,7 @@ extern const char gfar_driver_version[];
251#define IEVENT_FIQ 0x00000004 251#define IEVENT_FIQ 0x00000004
252#define IEVENT_DPE 0x00000002 252#define IEVENT_DPE 0x00000002
253#define IEVENT_PERR 0x00000001 253#define IEVENT_PERR 0x00000001
254#define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0) 254#define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0 | IEVENT_BSY)
255#define IEVENT_TX_MASK (IEVENT_TXB | IEVENT_TXF) 255#define IEVENT_TX_MASK (IEVENT_TXB | IEVENT_TXF)
256#define IEVENT_RTX_MASK (IEVENT_RX_MASK | IEVENT_TX_MASK) 256#define IEVENT_RTX_MASK (IEVENT_RX_MASK | IEVENT_TX_MASK)
257#define IEVENT_ERR_MASK \ 257#define IEVENT_ERR_MASK \