diff options
author | Dai Haruki <dai.haruki@freescale.com> | 2008-12-17 19:52:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-17 19:52:00 -0500 |
commit | 8c7396aebb68994c0519e438eecdf4d5fa9c7844 (patch) | |
tree | 9d4d71f7f5fb7a47348b7821526d85c3eacb6ff3 | |
parent | c50a5d9aedef5b0b289d07f6d73934d394e50b3f (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.c | 59 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 2 |
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 */ | 1607 | static void gfar_schedule_cleanup(struct net_device *dev) |
1608 | static 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 | 1617 | static 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 | ||
1714 | irqreturn_t gfar_receive(int irq, void *dev_id) | 1704 | irqreturn_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 \ |