diff options
Diffstat (limited to 'drivers/net/tc35815.c')
-rw-r--r-- | drivers/net/tc35815.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d737f6b8f876..d1298e5b72c5 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -23,9 +23,9 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifdef TC35815_NAPI | 25 | #ifdef TC35815_NAPI |
26 | #define DRV_VERSION "1.37-NAPI" | 26 | #define DRV_VERSION "1.38-NAPI" |
27 | #else | 27 | #else |
28 | #define DRV_VERSION "1.37" | 28 | #define DRV_VERSION "1.38" |
29 | #endif | 29 | #endif |
30 | static const char *version = "tc35815.c:v" DRV_VERSION "\n"; | 30 | static const char *version = "tc35815.c:v" DRV_VERSION "\n"; |
31 | #define MODNAME "tc35815" | 31 | #define MODNAME "tc35815" |
@@ -341,8 +341,9 @@ struct BDesc { | |||
341 | Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \ | 341 | Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \ |
342 | Tx_En) /* maybe 0x7b01 */ | 342 | Tx_En) /* maybe 0x7b01 */ |
343 | #endif | 343 | #endif |
344 | /* Do not use Rx_StripCRC -- it causes trouble on BLEx/FDAEx condition */ | ||
344 | #define RX_CTL_CMD (Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \ | 345 | #define RX_CTL_CMD (Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \ |
345 | | Rx_EnCRCErr | Rx_EnAlign | Rx_StripCRC | Rx_RxEn) /* maybe 0x6f11 */ | 346 | | Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn) /* maybe 0x6f01 */ |
346 | #define INT_EN_CMD (Int_NRAbtEn | \ | 347 | #define INT_EN_CMD (Int_NRAbtEn | \ |
347 | Int_DmParErrEn | Int_DParDEn | Int_DParErrEn | \ | 348 | Int_DmParErrEn | Int_DParDEn | Int_DParErrEn | \ |
348 | Int_SSysErrEn | Int_RMasAbtEn | Int_RTargAbtEn | \ | 349 | Int_SSysErrEn | Int_RMasAbtEn | Int_RTargAbtEn | \ |
@@ -593,9 +594,10 @@ static int tc_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
593 | struct net_device *dev = bus->priv; | 594 | struct net_device *dev = bus->priv; |
594 | struct tc35815_regs __iomem *tr = | 595 | struct tc35815_regs __iomem *tr = |
595 | (struct tc35815_regs __iomem *)dev->base_addr; | 596 | (struct tc35815_regs __iomem *)dev->base_addr; |
596 | unsigned long timeout = jiffies + 10; | 597 | unsigned long timeout = jiffies + HZ; |
597 | 598 | ||
598 | tc_writel(MD_CA_Busy | (mii_id << 5) | (regnum & 0x1f), &tr->MD_CA); | 599 | tc_writel(MD_CA_Busy | (mii_id << 5) | (regnum & 0x1f), &tr->MD_CA); |
600 | udelay(12); /* it takes 32 x 400ns at least */ | ||
599 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { | 601 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { |
600 | if (time_after(jiffies, timeout)) | 602 | if (time_after(jiffies, timeout)) |
601 | return -EIO; | 603 | return -EIO; |
@@ -609,11 +611,12 @@ static int tc_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 val) | |||
609 | struct net_device *dev = bus->priv; | 611 | struct net_device *dev = bus->priv; |
610 | struct tc35815_regs __iomem *tr = | 612 | struct tc35815_regs __iomem *tr = |
611 | (struct tc35815_regs __iomem *)dev->base_addr; | 613 | (struct tc35815_regs __iomem *)dev->base_addr; |
612 | unsigned long timeout = jiffies + 10; | 614 | unsigned long timeout = jiffies + HZ; |
613 | 615 | ||
614 | tc_writel(val, &tr->MD_Data); | 616 | tc_writel(val, &tr->MD_Data); |
615 | tc_writel(MD_CA_Busy | MD_CA_Wr | (mii_id << 5) | (regnum & 0x1f), | 617 | tc_writel(MD_CA_Busy | MD_CA_Wr | (mii_id << 5) | (regnum & 0x1f), |
616 | &tr->MD_CA); | 618 | &tr->MD_CA); |
619 | udelay(12); /* it takes 32 x 400ns at least */ | ||
617 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { | 620 | while (tc_readl(&tr->MD_CA) & MD_CA_Busy) { |
618 | if (time_after(jiffies, timeout)) | 621 | if (time_after(jiffies, timeout)) |
619 | return -EIO; | 622 | return -EIO; |
@@ -1509,7 +1512,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1509 | */ | 1512 | */ |
1510 | 1513 | ||
1511 | spin_unlock_irqrestore(&lp->lock, flags); | 1514 | spin_unlock_irqrestore(&lp->lock, flags); |
1512 | return 0; | 1515 | return NETDEV_TX_OK; |
1513 | } | 1516 | } |
1514 | 1517 | ||
1515 | #define FATAL_ERROR_INT \ | 1518 | #define FATAL_ERROR_INT \ |
@@ -1540,8 +1543,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status) | |||
1540 | #endif | 1543 | #endif |
1541 | { | 1544 | { |
1542 | struct tc35815_local *lp = netdev_priv(dev); | 1545 | struct tc35815_local *lp = netdev_priv(dev); |
1543 | struct tc35815_regs __iomem *tr = | ||
1544 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
1545 | int ret = -1; | 1546 | int ret = -1; |
1546 | 1547 | ||
1547 | /* Fatal errors... */ | 1548 | /* Fatal errors... */ |
@@ -1551,27 +1552,26 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status) | |||
1551 | } | 1552 | } |
1552 | /* recoverable errors */ | 1553 | /* recoverable errors */ |
1553 | if (status & Int_IntFDAEx) { | 1554 | if (status & Int_IntFDAEx) { |
1554 | /* disable FDAEx int. (until we make rooms...) */ | 1555 | if (netif_msg_rx_err(lp)) |
1555 | tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En); | 1556 | dev_warn(&dev->dev, |
1556 | printk(KERN_WARNING | 1557 | "Free Descriptor Area Exhausted (%#x).\n", |
1557 | "%s: Free Descriptor Area Exhausted (%#x).\n", | 1558 | status); |
1558 | dev->name, status); | ||
1559 | dev->stats.rx_dropped++; | 1559 | dev->stats.rx_dropped++; |
1560 | ret = 0; | 1560 | ret = 0; |
1561 | } | 1561 | } |
1562 | if (status & Int_IntBLEx) { | 1562 | if (status & Int_IntBLEx) { |
1563 | /* disable BLEx int. (until we make rooms...) */ | 1563 | if (netif_msg_rx_err(lp)) |
1564 | tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En); | 1564 | dev_warn(&dev->dev, |
1565 | printk(KERN_WARNING | 1565 | "Buffer List Exhausted (%#x).\n", |
1566 | "%s: Buffer List Exhausted (%#x).\n", | 1566 | status); |
1567 | dev->name, status); | ||
1568 | dev->stats.rx_dropped++; | 1567 | dev->stats.rx_dropped++; |
1569 | ret = 0; | 1568 | ret = 0; |
1570 | } | 1569 | } |
1571 | if (status & Int_IntExBD) { | 1570 | if (status & Int_IntExBD) { |
1572 | printk(KERN_WARNING | 1571 | if (netif_msg_rx_err(lp)) |
1573 | "%s: Excessive Buffer Descriptiors (%#x).\n", | 1572 | dev_warn(&dev->dev, |
1574 | dev->name, status); | 1573 | "Excessive Buffer Descriptiors (%#x).\n", |
1574 | status); | ||
1575 | dev->stats.rx_length_errors++; | 1575 | dev->stats.rx_length_errors++; |
1576 | ret = 0; | 1576 | ret = 0; |
1577 | } | 1577 | } |
@@ -1630,8 +1630,12 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id) | |||
1630 | 1630 | ||
1631 | spin_lock(&lp->lock); | 1631 | spin_lock(&lp->lock); |
1632 | status = tc_readl(&tr->Int_Src); | 1632 | status = tc_readl(&tr->Int_Src); |
1633 | tc_writel(status, &tr->Int_Src); /* write to clear */ | 1633 | /* BLEx, FDAEx will be cleared later */ |
1634 | tc_writel(status & ~(Int_BLEx | Int_FDAEx), | ||
1635 | &tr->Int_Src); /* write to clear */ | ||
1634 | handled = tc35815_do_interrupt(dev, status); | 1636 | handled = tc35815_do_interrupt(dev, status); |
1637 | if (status & (Int_BLEx | Int_FDAEx)) | ||
1638 | tc_writel(status & (Int_BLEx | Int_FDAEx), &tr->Int_Src); | ||
1635 | (void)tc_readl(&tr->Int_Src); /* flush */ | 1639 | (void)tc_readl(&tr->Int_Src); /* flush */ |
1636 | spin_unlock(&lp->lock); | 1640 | spin_unlock(&lp->lock); |
1637 | return IRQ_RETVAL(handled >= 0); | 1641 | return IRQ_RETVAL(handled >= 0); |
@@ -1659,8 +1663,6 @@ tc35815_rx(struct net_device *dev) | |||
1659 | struct tc35815_local *lp = netdev_priv(dev); | 1663 | struct tc35815_local *lp = netdev_priv(dev); |
1660 | unsigned int fdctl; | 1664 | unsigned int fdctl; |
1661 | int i; | 1665 | int i; |
1662 | int buf_free_count = 0; | ||
1663 | int fd_free_count = 0; | ||
1664 | #ifdef TC35815_NAPI | 1666 | #ifdef TC35815_NAPI |
1665 | int received = 0; | 1667 | int received = 0; |
1666 | #endif | 1668 | #endif |
@@ -1769,8 +1771,9 @@ tc35815_rx(struct net_device *dev) | |||
1769 | dev->stats.rx_bytes += pkt_len; | 1771 | dev->stats.rx_bytes += pkt_len; |
1770 | } else { | 1772 | } else { |
1771 | dev->stats.rx_errors++; | 1773 | dev->stats.rx_errors++; |
1772 | printk(KERN_DEBUG "%s: Rx error (status %x)\n", | 1774 | if (netif_msg_rx_err(lp)) |
1773 | dev->name, status & Rx_Stat_Mask); | 1775 | dev_info(&dev->dev, "Rx error (status %x)\n", |
1776 | status & Rx_Stat_Mask); | ||
1774 | /* WORKAROUND: LongErr and CRCErr means Overflow. */ | 1777 | /* WORKAROUND: LongErr and CRCErr means Overflow. */ |
1775 | if ((status & Rx_LongErr) && (status & Rx_CRCErr)) { | 1778 | if ((status & Rx_LongErr) && (status & Rx_CRCErr)) { |
1776 | status &= ~(Rx_LongErr|Rx_CRCErr); | 1779 | status &= ~(Rx_LongErr|Rx_CRCErr); |
@@ -1848,7 +1851,6 @@ tc35815_rx(struct net_device *dev) | |||
1848 | #else | 1851 | #else |
1849 | lp->fbl_count++; | 1852 | lp->fbl_count++; |
1850 | #endif | 1853 | #endif |
1851 | buf_free_count++; | ||
1852 | } | 1854 | } |
1853 | } | 1855 | } |
1854 | 1856 | ||
@@ -1870,7 +1872,6 @@ tc35815_rx(struct net_device *dev) | |||
1870 | #endif | 1872 | #endif |
1871 | lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD); | 1873 | lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD); |
1872 | lp->rfd_cur++; | 1874 | lp->rfd_cur++; |
1873 | fd_free_count++; | ||
1874 | } | 1875 | } |
1875 | if (lp->rfd_cur > lp->rfd_limit) | 1876 | if (lp->rfd_cur > lp->rfd_limit) |
1876 | lp->rfd_cur = lp->rfd_base; | 1877 | lp->rfd_cur = lp->rfd_base; |
@@ -1881,17 +1882,6 @@ tc35815_rx(struct net_device *dev) | |||
1881 | #endif | 1882 | #endif |
1882 | } | 1883 | } |
1883 | 1884 | ||
1884 | /* re-enable BL/FDA Exhaust interrupts. */ | ||
1885 | if (fd_free_count) { | ||
1886 | struct tc35815_regs __iomem *tr = | ||
1887 | (struct tc35815_regs __iomem *)dev->base_addr; | ||
1888 | u32 en, en_old = tc_readl(&tr->Int_En); | ||
1889 | en = en_old | Int_FDAExEn; | ||
1890 | if (buf_free_count) | ||
1891 | en |= Int_BLExEn; | ||
1892 | if (en != en_old) | ||
1893 | tc_writel(en, &tr->Int_En); | ||
1894 | } | ||
1895 | #ifdef TC35815_NAPI | 1885 | #ifdef TC35815_NAPI |
1896 | return received; | 1886 | return received; |
1897 | #endif | 1887 | #endif |
@@ -1910,9 +1900,14 @@ static int tc35815_poll(struct napi_struct *napi, int budget) | |||
1910 | spin_lock(&lp->lock); | 1900 | spin_lock(&lp->lock); |
1911 | status = tc_readl(&tr->Int_Src); | 1901 | status = tc_readl(&tr->Int_Src); |
1912 | do { | 1902 | do { |
1913 | tc_writel(status, &tr->Int_Src); /* write to clear */ | 1903 | /* BLEx, FDAEx will be cleared later */ |
1904 | tc_writel(status & ~(Int_BLEx | Int_FDAEx), | ||
1905 | &tr->Int_Src); /* write to clear */ | ||
1914 | 1906 | ||
1915 | handled = tc35815_do_interrupt(dev, status, budget - received); | 1907 | handled = tc35815_do_interrupt(dev, status, budget - received); |
1908 | if (status & (Int_BLEx | Int_FDAEx)) | ||
1909 | tc_writel(status & (Int_BLEx | Int_FDAEx), | ||
1910 | &tr->Int_Src); | ||
1916 | if (handled >= 0) { | 1911 | if (handled >= 0) { |
1917 | received += handled; | 1912 | received += handled; |
1918 | if (received >= budget) | 1913 | if (received >= budget) |
@@ -2144,7 +2139,7 @@ static struct net_device_stats *tc35815_get_stats(struct net_device *dev) | |||
2144 | (struct tc35815_regs __iomem *)dev->base_addr; | 2139 | (struct tc35815_regs __iomem *)dev->base_addr; |
2145 | if (netif_running(dev)) | 2140 | if (netif_running(dev)) |
2146 | /* Update the statistics from the device registers. */ | 2141 | /* Update the statistics from the device registers. */ |
2147 | dev->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt); | 2142 | dev->stats.rx_missed_errors += tc_readl(&tr->Miss_Cnt); |
2148 | 2143 | ||
2149 | return &dev->stats; | 2144 | return &dev->stats; |
2150 | } | 2145 | } |
@@ -2399,8 +2394,6 @@ static void tc35815_chip_init(struct net_device *dev) | |||
2399 | tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl); | 2394 | tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl); |
2400 | #ifdef TC35815_USE_PACKEDBUFFER | 2395 | #ifdef TC35815_USE_PACKEDBUFFER |
2401 | tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize); /* Packing */ | 2396 | tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize); /* Packing */ |
2402 | #else | ||
2403 | tc_writel(ETH_ZLEN, &tr->RxFragSize); | ||
2404 | #endif | 2397 | #endif |
2405 | tc_writel(0, &tr->TxPollCtr); /* Batch mode */ | 2398 | tc_writel(0, &tr->TxPollCtr); /* Batch mode */ |
2406 | tc_writel(TX_THRESHOLD, &tr->TxThrsh); | 2399 | tc_writel(TX_THRESHOLD, &tr->TxThrsh); |