This patch fixes various bugfixes spotted by Stephen, thanks !

- add functions to allocate/free TX and RX buffers
- recover from transmit timeout and use the 4 helpers defined below
- use netdev_alloc_skb instead of dev_alloc_skb
- do not use a private stats structure to store statistics
- break each TX/RX error to a separate line for better reading
- suppress volatiles and make checkpatch happy
- better control of the timer
- fix spin_unlock_irq typo in netdev_get_settings
- fix various typos and spelling in the driver

Signed-off-by: Florian Fainelli <[EMAIL PROTECTED]>
-- 
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index edce5a4..529c903 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -172,7 +172,6 @@ struct r6040_private {
        struct net_device *dev;
        struct mii_if_info mii_if;
        struct napi_struct napi;
-       struct net_device_stats stats;
        u16     napi_rx_running;
        void __iomem *base;
 };
@@ -233,18 +232,121 @@ static void mdio_write(struct net_device *dev, int 
mii_id, int reg, int val)
        phy_write(ioaddr, lp->phy_addr, reg, val);
 }
 
+static void r6040_free_txbufs(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       int i;
+
+       for (i = 0; i < TX_DCNT; i++) {
+               if (lp->tx_insert_ptr->skb_ptr) {
+                       pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+                               MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+                       dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
+                       lp->rx_insert_ptr->skb_ptr = NULL;
+               }
+               lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
+       }
+}
+
+static void r6040_free_rxbufs(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       int i;
+
+       for (i = 0; i < RX_DCNT; i++) {
+               if (lp->rx_insert_ptr->skb_ptr) {
+                       pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
+                       lp->rx_insert_ptr->skb_ptr = NULL;
+               }
+               lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
+       }
+}
+
+static void r6040_alloc_txbufs(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       struct r6040_descriptor *descptr;
+       int i;
+       dma_addr_t desc_dma, start_dma;
+
+       lp->tx_free_desc = TX_DCNT;
+       /* Zero all descriptors */
+       memset(lp->desc_pool, 0, ALLOC_DESC_SIZE);
+       lp->tx_insert_ptr = (struct r6040_descriptor *)lp->desc_pool;
+       lp->tx_remove_ptr = lp->tx_insert_ptr;
+
+       /* Init TX descriptor */
+       descptr = lp->tx_insert_ptr;
+       desc_dma = lp->desc_dma;
+       start_dma = desc_dma;
+       for (i = 0; i < TX_DCNT; i++) {
+               descptr->ndesc = cpu_to_le32(desc_dma +
+                       sizeof(struct r6040_descriptor));
+               descptr->vndescp = (descptr + 1);
+               descptr = (descptr + 1);
+               desc_dma += sizeof(struct r6040_descriptor);
+       }
+       (descptr - 1)->ndesc = cpu_to_le32(start_dma);
+       (descptr - 1)->vndescp = lp->tx_insert_ptr;
+}
+
+static void r6040_alloc_rxbufs(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       struct r6040_descriptor *descptr;
+       int i;
+       dma_addr_t desc_dma, start_dma;
+
+       lp->rx_free_desc = 0;
+       /* Zero all descriptors */
+       memset(lp->desc_pool, 0, ALLOC_DESC_SIZE);
+       lp->rx_insert_ptr = (struct r6040_descriptor *)lp->tx_insert_ptr +
+               TX_DCNT;
+       lp->rx_remove_ptr = lp->rx_insert_ptr;
+
+       /* Init RX descriptor */
+       start_dma = desc_dma;
+       descptr = lp->rx_insert_ptr;
+       for (i = 0; i < RX_DCNT; i++) {
+               descptr->ndesc = cpu_to_le32(desc_dma +
+                       sizeof(struct r6040_descriptor));
+               descptr->vndescp = (descptr + 1);
+               descptr = (descptr + 1);
+               desc_dma += sizeof(struct r6040_descriptor);
+       }
+       (descptr - 1)->ndesc = cpu_to_le32(start_dma);
+       (descptr - 1)->vndescp = lp->rx_insert_ptr;
+}
+
 static void
 r6040_tx_timeout(struct net_device *dev)
 {
        struct r6040_private *priv = netdev_priv(dev);
+       void __iomem *ioaddr = priv->base;
 
+       printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status "
+               "%4.4x\n",
+               dev->name, ioread16(ioaddr + MIER),
+               mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));
        disable_irq(dev->irq);
        napi_disable(&priv->napi);
+
        spin_lock(&priv->lock);
-       dev->stats.tx_errors++;
+       /* Clear all descriptors */
+       r6040_free_txbufs(dev);
+       r6040_free_rxbufs(dev);
+       r6040_alloc_txbufs(dev);
+       r6040_alloc_rxbufs(dev);
+
+       /* Reset MAC */
+       iowrite16(MAC_RST, ioaddr + MCR1);
        spin_unlock(&priv->lock);
+       enable_irq(dev->irq);
 
-       netif_stop_queue(dev);
+       dev->stats.tx_errors++;
+       netif_wake_queue(dev);
 }
 
 /* Allocate skb buffer for rx descriptor */
@@ -255,7 +357,7 @@ static void rx_buf_alloc(struct r6040_private *lp, struct 
net_device *dev)
 
        descptr = lp->rx_insert_ptr;
        while (lp->rx_free_desc < RX_DCNT) {
-               descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
+               descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE);
 
                if (!descptr->skb_ptr)
                        break;
@@ -279,11 +381,11 @@ static struct net_device_stats *r6040_get_stats(struct 
net_device *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
-       priv->stats.multicast += ioread8(ioaddr + ME_CNT0);
+       dev->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
+       dev->stats.multicast += ioread8(ioaddr + ME_CNT0);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return &priv->stats;
+       return &dev->stats;
 }
 
 /* Stop RDC MAC and Free the allocated resource */
@@ -291,7 +393,6 @@ static void r6040_down(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
-       int i;
        int limit = 2048;
        u16 *adrp;
        u16 cmd;
@@ -312,26 +413,9 @@ static void r6040_down(struct net_device *dev)
        iowrite16(adrp[2], ioaddr + MID_0H);
        free_irq(dev->irq, dev);
        /* Free RX buffer */
-       for (i = 0; i < RX_DCNT; i++) {
-               if (lp->rx_insert_ptr->skb_ptr) {
-                       pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
-                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-                       dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
-                       lp->rx_insert_ptr->skb_ptr = NULL;
-               }
-               lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
-       }
-
+       r6040_free_rxbufs(dev);
        /* Free TX buffer */
-       for (i = 0; i < TX_DCNT; i++) {
-               if (lp->tx_insert_ptr->skb_ptr) {
-                       pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
-                               MAX_BUF_SIZE, PCI_DMA_TODEVICE);
-                       dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
-                       lp->rx_insert_ptr->skb_ptr = NULL;
-               }
-               lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
-       }
+       r6040_free_txbufs(dev);
 
        /* Free Descriptor memory */
        pci_free_consistent(lp->pdev, ALLOC_DESC_SIZE,
@@ -431,19 +515,20 @@ static int r6040_rx(struct net_device *dev, int limit)
 
                /* Check for errors */
                err = ioread16(ioaddr + MLSR);
-               if (err & 0x0400) priv->stats.rx_errors++;
+               if (err & 0x0400) dev->stats.rx_errors++;
                /* RX FIFO over-run */
-               if (err & 0x8000) priv->stats.rx_fifo_errors++;
+               if (err & 0x8000) dev->stats.rx_fifo_errors++;
                /* RX descriptor unavailable */
-               if (err & 0x0080) priv->stats.rx_frame_errors++;
+               if (err & 0x0080) dev->stats.rx_frame_errors++;
                /* Received packet with length over buffer lenght */
-               if (err & 0x0020) priv->stats.rx_over_errors++;
-               /* Received packet with too long or short */
-               if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++;
+               if (err & 0x0020) dev->stats.rx_over_errors++;
+               /* Received packet too long or short */
+               if (err & 0x0010) dev->stats.rx_lenght_errors++;
+               if (err & 0x0008) dev->stats.rx_length_errors++;
                /* Received packet with CRC errors */
                if (err & 0x0004) {
                        spin_lock(&priv->lock);
-                       priv->stats.rx_crc_errors++;
+                       dev->stats.rx_crc_errors++;
                        spin_unlock(&priv->lock);
                }
 
@@ -468,8 +553,8 @@ static int r6040_rx(struct net_device *dev, int limit)
                        /* Send to upper layer */
                        netif_receive_skb(skb_ptr);
                        dev->last_rx = jiffies;
-                       priv->dev->stats.rx_packets++;
-                       priv->dev->stats.rx_bytes += descptr->len;
+                       dev->stats.rx_packets++;
+                       dev->stats.rx_bytes += descptr->len;
                        /* To next descriptor */
                        descptr = descptr->vndescp;
                        priv->rx_free_desc--;
@@ -497,11 +582,12 @@ static void r6040_tx(struct net_device *dev)
                /* Check for errors */
                err = ioread16(ioaddr + MLSR);
 
-               if (err & 0x0200) priv->stats.rx_fifo_errors++;
-               if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++;
+               if (err & 0x0200) dev->stats.tx_fifo_errors++;
+               if (err & 0x2000) dev->stats.tx_carrier_errors++;
+               if (err & 0x4000) dev->stats.tx_carrier_errors++;
 
                if (descptr->status & 0x8000)
-                       break; /* Not complte */
+                       break; /* Not complete */
                skb_ptr = descptr->skb_ptr;
                pci_unmap_single(priv->pdev, descptr->buf,
                        skb_ptr->len, PCI_DMA_TODEVICE);
@@ -544,7 +630,6 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
        u16 status;
-       int handled = 1;
 
        /* Mask off RDC MAC interrupt */
        iowrite16(MSK_INT, ioaddr + MIER);
@@ -564,7 +649,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
        if (status & 0x10)
                r6040_tx(dev);
 
-       return IRQ_RETVAL(handled);
+       return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -581,61 +666,24 @@ static void r6040_poll_controller(struct net_device *dev)
 static void r6040_up(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
-       struct r6040_descriptor *descptr;
-       void __iomem *ioaddr = lp->base;
-       int i;
        __le32 tmp_addr;
-       dma_addr_t desc_dma, start_dma;
-
-       /* Initialize */
-       lp->tx_free_desc = TX_DCNT;
-       lp->rx_free_desc = 0;
-       /* Init descriptor */
-       memset(lp->desc_pool, 0, ALLOC_DESC_SIZE); /* Let all descriptor = 0 */
-       lp->tx_insert_ptr = (struct r6040_descriptor *)lp->desc_pool;
-       lp->tx_remove_ptr = lp->tx_insert_ptr;
-       lp->rx_insert_ptr = (struct r6040_descriptor *)lp->tx_insert_ptr +
-               TX_DCNT;
-       lp->rx_remove_ptr = lp->rx_insert_ptr;
-       /* Init TX descriptor */
-       descptr = lp->tx_insert_ptr;
-       desc_dma = lp->desc_dma;
-       start_dma = desc_dma;
-       for (i = 0; i < TX_DCNT; i++) {
-               descptr->ndesc = cpu_to_le32(desc_dma +
-                       sizeof(struct r6040_descriptor));
-               descptr->vndescp = (descptr + 1);
-               descptr = (descptr + 1);
-               desc_dma += sizeof(struct r6040_descriptor);
-       }
-       (descptr - 1)->ndesc = cpu_to_le32(start_dma);
-       (descptr - 1)->vndescp = lp->tx_insert_ptr;
+       void __iomem *ioaddr = lp->base;
 
-       /* Init RX descriptor */
-       start_dma = desc_dma;
-       descptr = lp->rx_insert_ptr;
-       for (i = 0; i < RX_DCNT; i++) {
-               descptr->ndesc = cpu_to_le32(desc_dma +
-                       sizeof(struct r6040_descriptor));
-               descptr->vndescp = (descptr + 1);
-               descptr = (descptr + 1);
-               desc_dma += sizeof(struct r6040_descriptor);
-       }
-       (descptr - 1)->ndesc = cpu_to_le32(start_dma);
-       (descptr - 1)->vndescp = lp->rx_insert_ptr;
+       r6040_alloc_txbufs(dev);
+       r6040_alloc_rxbufs(dev);
 
        /* Allocate buffer for RX descriptor */
        rx_buf_alloc(lp, dev);
 
        /* TX and RX descriptor start Register */
        tmp_addr = cpu_to_le32((u32)lp->tx_insert_ptr);
-       tmp_addr = virt_to_bus((volatile void *)tmp_addr);
+       tmp_addr = virt_to_bus((void *)tmp_addr);
        /* Lower 16-bits to MTD_SA0 */
        iowrite16(tmp_addr, ioaddr + MTD_SA0);
        /* Higher 16-bits to MTD_SA1 */
        iowrite16((u16)(tmp_addr >> 16), ioaddr + MTD_SA1);
        tmp_addr = cpu_to_le32((u32)lp->rx_insert_ptr);
-       tmp_addr = virt_to_bus((volatile void *)tmp_addr);
+       tmp_addr = virt_to_bus((void *)tmp_addr);
        iowrite16(tmp_addr, ioaddr + MRD_SA0);
        iowrite16((u16)(tmp_addr >> 16), ioaddr + MRD_SA1);
 
@@ -703,8 +751,7 @@ static void r6040_timer(unsigned long data)
        }
 
        /* Timer active again */
-       lp->timer.expires = TIMER_WUT;
-       add_timer(&lp->timer);
+       mod_timer(&lp->timer, jiffies + round_jiffies(HZ));
 }
 
 /* Read/set MAC address routines */
@@ -756,10 +803,8 @@ r6040_open(struct net_device *dev)
        if (lp->switch_sig != ICPLUS_PHY_ID) {
                /* set and active a timer process */
                init_timer(&lp->timer);
-               lp->timer.expires = TIMER_WUT;
                lp->timer.data = (unsigned long)dev;
                lp->timer.function = &r6040_timer;
-               add_timer(&lp->timer);
        }
        return 0;
 }
@@ -773,12 +818,9 @@ r6040_start_xmit(struct sk_buff *skb, struct net_device 
*dev)
        unsigned long flags;
        int ret;
 
-       if (!skb)       /* NULL skb directly return */
-               return ret;
-
        if (skb->len >= MAX_BUF_SIZE) { /* Packet too long, drop it */
                dev_kfree_skb(skb);
-               return ret;
+               return NETDEV_TX_OK;
        }
 
        /* Critical Section */
@@ -788,8 +830,7 @@ r6040_start_xmit(struct sk_buff *skb, struct net_device 
*dev)
        if (!lp->tx_free_desc) {
                spin_unlock_irqrestore(&lp->lock, flags);
                printk(KERN_ERR DRV_NAME ": no tx descriptor\n");
-               ret = 1;
-               return ret;
+               return NETDEV_TX_BUSY;
        }
 
        /* Statistic Counter */
@@ -916,7 +957,7 @@ static int netdev_get_settings(struct net_device *dev, 
struct ethtool_cmd *cmd)
 
        spin_lock_irq(&rp->lock);
        rc = mii_ethtool_gset(&rp->mii_if, cmd);
-       spin_unlock_irq(&rp->mii_if);
+       spin_unlock_irq(&rp->lock);
 
        return rc;
 }
@@ -1082,7 +1123,7 @@ static void __devexit r6040_remove_one(struct pci_dev 
*pdev)
 
 static struct pci_device_id r6040_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6040) },
-       {0 }
+       { 0 }
 };
 MODULE_DEVICE_TABLE(pci, r6040_pci_tbl);
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to