aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sis900.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 23b713c700b3..1d4d88680db1 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *net_dev)
1696 long ioaddr = net_dev->base_addr; 1696 long ioaddr = net_dev->base_addr;
1697 unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC; 1697 unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
1698 u32 rx_status = sis_priv->rx_ring[entry].cmdsts; 1698 u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
1699 int rx_work_limit;
1699 1700
1700 if (netif_msg_rx_status(sis_priv)) 1701 if (netif_msg_rx_status(sis_priv))
1701 printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d " 1702 printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
1702 "status:0x%8.8x\n", 1703 "status:0x%8.8x\n",
1703 sis_priv->cur_rx, sis_priv->dirty_rx, rx_status); 1704 sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
1705 rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
1704 1706
1705 while (rx_status & OWN) { 1707 while (rx_status & OWN) {
1706 unsigned int rx_size; 1708 unsigned int rx_size;
1707 1709
1710 if (--rx_work_limit < 0)
1711 break;
1712
1708 rx_size = (rx_status & DSIZE) - CRC_SIZE; 1713 rx_size = (rx_status & DSIZE) - CRC_SIZE;
1709 1714
1710 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { 1715 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *net_dev)
1732 we are working on NULL sk_buff :-( */ 1737 we are working on NULL sk_buff :-( */
1733 if (sis_priv->rx_skbuff[entry] == NULL) { 1738 if (sis_priv->rx_skbuff[entry] == NULL) {
1734 if (netif_msg_rx_err(sis_priv)) 1739 if (netif_msg_rx_err(sis_priv))
1735 printk(KERN_INFO "%s: NULL pointer " 1740 printk(KERN_WARNING "%s: NULL pointer "
1736 "encountered in Rx ring, skipping\n", 1741 "encountered in Rx ring\n"
1737 net_dev->name); 1742 "cur_rx:%4.4d, dirty_rx:%4.4d\n",
1743 net_dev->name, sis_priv->cur_rx,
1744 sis_priv->dirty_rx);
1738 break; 1745 break;
1739 } 1746 }
1740 1747
@@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
1770 sis_priv->rx_ring[entry].cmdsts = 0; 1777 sis_priv->rx_ring[entry].cmdsts = 0;
1771 sis_priv->rx_ring[entry].bufptr = 0; 1778 sis_priv->rx_ring[entry].bufptr = 0;
1772 sis_priv->stats.rx_dropped++; 1779 sis_priv->stats.rx_dropped++;
1780 sis_priv->cur_rx++;
1773 break; 1781 break;
1774 } 1782 }
1775 skb->dev = net_dev; 1783 skb->dev = net_dev;
@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *net_dev)
1787 1795
1788 /* refill the Rx buffer, what if the rate of refilling is slower 1796 /* refill the Rx buffer, what if the rate of refilling is slower
1789 * than consuming ?? */ 1797 * than consuming ?? */
1790 for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) { 1798 for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
1791 struct sk_buff *skb; 1799 struct sk_buff *skb;
1792 1800
1793 entry = sis_priv->dirty_rx % NUM_RX_DESC; 1801 entry = sis_priv->dirty_rx % NUM_RX_DESC;