aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2009-08-06 00:41:46 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-06 16:14:22 -0400
commitdb30f5ef6e4471fd55671382b8870fdd61e35814 (patch)
tree62307b1346a56025edc1fe17482e92adc6bd7d27
parent297713decac17527d3583fcd4d18564568cac759 (diff)
tc35815: Improve BLEx / FDAEx handling
Clear Int_BLEx / Int_FDAEx after (not before) processing Rx interrupt. This will reduce number of unnecessary interrupts. Also print rx error messages only if netif_msg_rx_err() enabled. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tc35815.c60
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index a7581632f811..62965d6665d2 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1541,8 +1541,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status)
1541#endif 1541#endif
1542{ 1542{
1543 struct tc35815_local *lp = netdev_priv(dev); 1543 struct tc35815_local *lp = netdev_priv(dev);
1544 struct tc35815_regs __iomem *tr =
1545 (struct tc35815_regs __iomem *)dev->base_addr;
1546 int ret = -1; 1544 int ret = -1;
1547 1545
1548 /* Fatal errors... */ 1546 /* Fatal errors... */
@@ -1552,27 +1550,26 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status)
1552 } 1550 }
1553 /* recoverable errors */ 1551 /* recoverable errors */
1554 if (status & Int_IntFDAEx) { 1552 if (status & Int_IntFDAEx) {
1555 /* disable FDAEx int. (until we make rooms...) */ 1553 if (netif_msg_rx_err(lp))
1556 tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En); 1554 dev_warn(&dev->dev,
1557 printk(KERN_WARNING 1555 "Free Descriptor Area Exhausted (%#x).\n",
1558 "%s: Free Descriptor Area Exhausted (%#x).\n", 1556 status);
1559 dev->name, status);
1560 dev->stats.rx_dropped++; 1557 dev->stats.rx_dropped++;
1561 ret = 0; 1558 ret = 0;
1562 } 1559 }
1563 if (status & Int_IntBLEx) { 1560 if (status & Int_IntBLEx) {
1564 /* disable BLEx int. (until we make rooms...) */ 1561 if (netif_msg_rx_err(lp))
1565 tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En); 1562 dev_warn(&dev->dev,
1566 printk(KERN_WARNING 1563 "Buffer List Exhausted (%#x).\n",
1567 "%s: Buffer List Exhausted (%#x).\n", 1564 status);
1568 dev->name, status);
1569 dev->stats.rx_dropped++; 1565 dev->stats.rx_dropped++;
1570 ret = 0; 1566 ret = 0;
1571 } 1567 }
1572 if (status & Int_IntExBD) { 1568 if (status & Int_IntExBD) {
1573 printk(KERN_WARNING 1569 if (netif_msg_rx_err(lp))
1574 "%s: Excessive Buffer Descriptiors (%#x).\n", 1570 dev_warn(&dev->dev,
1575 dev->name, status); 1571 "Excessive Buffer Descriptiors (%#x).\n",
1572 status);
1576 dev->stats.rx_length_errors++; 1573 dev->stats.rx_length_errors++;
1577 ret = 0; 1574 ret = 0;
1578 } 1575 }
@@ -1631,8 +1628,12 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
1631 1628
1632 spin_lock(&lp->lock); 1629 spin_lock(&lp->lock);
1633 status = tc_readl(&tr->Int_Src); 1630 status = tc_readl(&tr->Int_Src);
1634 tc_writel(status, &tr->Int_Src); /* write to clear */ 1631 /* BLEx, FDAEx will be cleared later */
1632 tc_writel(status & ~(Int_BLEx | Int_FDAEx),
1633 &tr->Int_Src); /* write to clear */
1635 handled = tc35815_do_interrupt(dev, status); 1634 handled = tc35815_do_interrupt(dev, status);
1635 if (status & (Int_BLEx | Int_FDAEx))
1636 tc_writel(status & (Int_BLEx | Int_FDAEx), &tr->Int_Src);
1636 (void)tc_readl(&tr->Int_Src); /* flush */ 1637 (void)tc_readl(&tr->Int_Src); /* flush */
1637 spin_unlock(&lp->lock); 1638 spin_unlock(&lp->lock);
1638 return IRQ_RETVAL(handled >= 0); 1639 return IRQ_RETVAL(handled >= 0);
@@ -1660,8 +1661,6 @@ tc35815_rx(struct net_device *dev)
1660 struct tc35815_local *lp = netdev_priv(dev); 1661 struct tc35815_local *lp = netdev_priv(dev);
1661 unsigned int fdctl; 1662 unsigned int fdctl;
1662 int i; 1663 int i;
1663 int buf_free_count = 0;
1664 int fd_free_count = 0;
1665#ifdef TC35815_NAPI 1664#ifdef TC35815_NAPI
1666 int received = 0; 1665 int received = 0;
1667#endif 1666#endif
@@ -1770,8 +1769,9 @@ tc35815_rx(struct net_device *dev)
1770 dev->stats.rx_bytes += pkt_len; 1769 dev->stats.rx_bytes += pkt_len;
1771 } else { 1770 } else {
1772 dev->stats.rx_errors++; 1771 dev->stats.rx_errors++;
1773 printk(KERN_DEBUG "%s: Rx error (status %x)\n", 1772 if (netif_msg_rx_err(lp))
1774 dev->name, status & Rx_Stat_Mask); 1773 dev_info(&dev->dev, "Rx error (status %x)\n",
1774 status & Rx_Stat_Mask);
1775 /* WORKAROUND: LongErr and CRCErr means Overflow. */ 1775 /* WORKAROUND: LongErr and CRCErr means Overflow. */
1776 if ((status & Rx_LongErr) && (status & Rx_CRCErr)) { 1776 if ((status & Rx_LongErr) && (status & Rx_CRCErr)) {
1777 status &= ~(Rx_LongErr|Rx_CRCErr); 1777 status &= ~(Rx_LongErr|Rx_CRCErr);
@@ -1849,7 +1849,6 @@ tc35815_rx(struct net_device *dev)
1849#else 1849#else
1850 lp->fbl_count++; 1850 lp->fbl_count++;
1851#endif 1851#endif
1852 buf_free_count++;
1853 } 1852 }
1854 } 1853 }
1855 1854
@@ -1871,7 +1870,6 @@ tc35815_rx(struct net_device *dev)
1871#endif 1870#endif
1872 lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD); 1871 lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD);
1873 lp->rfd_cur++; 1872 lp->rfd_cur++;
1874 fd_free_count++;
1875 } 1873 }
1876 if (lp->rfd_cur > lp->rfd_limit) 1874 if (lp->rfd_cur > lp->rfd_limit)
1877 lp->rfd_cur = lp->rfd_base; 1875 lp->rfd_cur = lp->rfd_base;
@@ -1882,17 +1880,6 @@ tc35815_rx(struct net_device *dev)
1882#endif 1880#endif
1883 } 1881 }
1884 1882
1885 /* re-enable BL/FDA Exhaust interrupts. */
1886 if (fd_free_count) {
1887 struct tc35815_regs __iomem *tr =
1888 (struct tc35815_regs __iomem *)dev->base_addr;
1889 u32 en, en_old = tc_readl(&tr->Int_En);
1890 en = en_old | Int_FDAExEn;
1891 if (buf_free_count)
1892 en |= Int_BLExEn;
1893 if (en != en_old)
1894 tc_writel(en, &tr->Int_En);
1895 }
1896#ifdef TC35815_NAPI 1883#ifdef TC35815_NAPI
1897 return received; 1884 return received;
1898#endif 1885#endif
@@ -1911,9 +1898,14 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
1911 spin_lock(&lp->lock); 1898 spin_lock(&lp->lock);
1912 status = tc_readl(&tr->Int_Src); 1899 status = tc_readl(&tr->Int_Src);
1913 do { 1900 do {
1914 tc_writel(status, &tr->Int_Src); /* write to clear */ 1901 /* BLEx, FDAEx will be cleared later */
1902 tc_writel(status & ~(Int_BLEx | Int_FDAEx),
1903 &tr->Int_Src); /* write to clear */
1915 1904
1916 handled = tc35815_do_interrupt(dev, status, budget - received); 1905 handled = tc35815_do_interrupt(dev, status, budget - received);
1906 if (status & (Int_BLEx | Int_FDAEx))
1907 tc_writel(status & (Int_BLEx | Int_FDAEx),
1908 &tr->Int_Src);
1917 if (handled >= 0) { 1909 if (handled >= 0) {
1918 received += handled; 1910 received += handled;
1919 if (received >= budget) 1911 if (received >= budget)