Hi,

I have made the following changes to our off-tree 2.6.22 smsc911x
driver, to make it run on 2.6.24-rc2. However the NAPI poll function
does not get called after an rx irq. Can you comment on what's wrong?

Thanks,
Bahadir


diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b7fe2f3..e5c6c4a 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -98,7 +98,6 @@ struct smsc911x_data {
        spinlock_t phy_lock;
        spinlock_t dev_lock;

-       struct net_device_stats stats;
        struct mii_if_info mii;
        unsigned int using_extphy;
        u32 msg_enable;
@@ -106,6 +105,8 @@ struct smsc911x_data {
        unsigned int gpio_setting;
        unsigned int gpio_orig_setting;
 #endif
+       struct net_device *netdev;
+       struct napi_struct napi;
        struct timer_list link_poll_timer;
        unsigned int stop_link_poll;

@@ -903,6 +904,7 @@ static unsigned int
smsc911x_tx_get_txstatcount(struct smsc911x_data *pdata)
 /* Reads tx statuses and increments counters where necessary */
 static void smsc911x_tx_update_txcounters(struct smsc911x_data *pdata)
 {
+       struct net_device *netdev = pdata->netdev;
        unsigned int tx_stat;

        while ((tx_stat = smsc911x_tx_get_txstatus(pdata)) != 0) {
@@ -917,24 +919,24 @@ static void smsc911x_tx_update_txcounters(struct
smsc911x_data *pdata)
                        SMSC_WARNING("Packet tag reserved bit is high");
                } else {
                        if (unlikely(tx_stat & 0x00008000)) {
-                               pdata->stats.tx_errors++;
+                               netdev->stats.tx_errors++;
                        } else {
-                               pdata->stats.tx_packets++;
-                               pdata->stats.tx_bytes += (tx_stat >> 16);
+                               netdev->stats.tx_packets++;
+                               netdev->stats.tx_bytes += (tx_stat >> 16);
                        }
                        if (unlikely(tx_stat & 0x00000100)) {
-                               pdata->stats.collisions += 16;
-                               pdata->stats.tx_aborted_errors += 1;
+                               netdev->stats.collisions += 16;
+                               netdev->stats.tx_aborted_errors += 1;
                        } else {
-                               pdata->stats.collisions +=
+                               netdev->stats.collisions +=
                                    ((tx_stat >> 3) & 0xF);
                        }
                        if (unlikely(tx_stat & 0x00000800)) {
-                               pdata->stats.tx_carrier_errors += 1;
+                               netdev->stats.tx_carrier_errors += 1;
                        }
                        if (unlikely(tx_stat & 0x00000200)) {
-                               pdata->stats.collisions++;
-                               pdata->stats.tx_aborted_errors++;
+                               netdev->stats.collisions++;
+                               netdev->stats.tx_aborted_errors++;
                        }
                }
        }
@@ -944,12 +946,13 @@ static void smsc911x_tx_update_txcounters(struct
smsc911x_data *pdata)
 static void
 smsc911x_rx_counterrors(struct smsc911x_data *pdata, unsigned int rxstat)
 {
+       struct net_device *netdev = pdata->netdev;
        int crc_err = 0;

        if (unlikely(rxstat & 0x00008000)) {
-               pdata->stats.rx_errors++;
+               netdev->stats.rx_errors++;
                if (unlikely(rxstat & 0x00000002)) {
-                       pdata->stats.rx_crc_errors++;
+                       netdev->stats.rx_crc_errors++;
                        crc_err = 1;
                }
        }
@@ -957,10 +960,10 @@ smsc911x_rx_counterrors(struct smsc911x_data
*pdata, unsigned int rxstat)
                if (unlikely((rxstat & 0x00001020) == 0x00001020)) {
                        /* Frame type indicates length,
                         * and length error is set */
-                       pdata->stats.rx_length_errors++;
+                       netdev->stats.rx_length_errors++;
                }
                if (rxstat & RX_STS_MCAST_)
-                       pdata->stats.multicast++;
+                       netdev->stats.multicast++;
        }
 }

@@ -990,13 +993,13 @@ smsc911x_rx_fastforward(struct smsc911x_data
*pdata, unsigned int pktbytes)
 }

 /* NAPI poll function */
-static int smsc911x_poll(struct net_device *dev, int *budget)
+static int smsc911x_poll(struct napi_struct *napi, int budget)
 {
-       struct smsc911x_data *pdata = netdev_priv(dev);
+       struct smsc911x_data *pdata = container_of(napi, struct smsc911x_data, 
napi);
+       struct net_device *dev = pdata->netdev;
        int npackets = 0;
-       int quota = min(dev->quota, *budget);

-       while (npackets < quota) {
+       while (npackets < budget) {
                unsigned int pktlength;
                unsigned int pktwords;
                unsigned int rxstat = smsc911x_rx_get_rxstatus(pdata);
@@ -1027,15 +1030,15 @@ static int smsc911x_poll(struct net_device
*dev, int *budget)
                                netif_receive_skb(skb);

                                /* Update counters */
-                               pdata->stats.rx_packets++;
-                               pdata->stats.rx_bytes += (pktlength - 4);
+                               dev->stats.rx_packets++;
+                               dev->stats.rx_bytes += (pktlength - 4);
                                dev->last_rx = jiffies;
                                npackets++;
                                continue;
                        } else {
                                SMSC_WARNING("Unable to allocate sk_buff "
                                             "for rx packet, in PIO path");
-                               pdata->stats.rx_dropped++;
+                               dev->stats.rx_dropped++;
                        }
                }
                /* At this point, the packet is to be read out
@@ -1043,25 +1046,21 @@ static int smsc911x_poll(struct net_device
*dev, int *budget)
                smsc911x_rx_fastforward(pdata, pktlength);
        }

-       pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
+       dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
        smsc911x_reg_write(INT_STS_RSFL_, pdata, INT_STS);

-       *budget -= npackets;
-       dev->quota -= npackets;
-
-       if (npackets < quota) {
+       if (npackets < budget) {
                unsigned int temp;
                /* We processed all packets available.  Tell NAPI it can
                 * stop polling then re-enable rx interrupts */
-               netif_rx_complete(dev);
+               netif_rx_complete(dev, napi);
                temp = smsc911x_reg_read(pdata, INT_EN);
                temp |= INT_EN_RSFL_EN_;
                smsc911x_reg_write(temp, pdata, INT_EN);
-               return 0;
        }

-       /* There are still packets waiting */
-       return 1;
+       /* Return total received packets */
+       return npackets;
 }

 /* Returns hash bit number for given MAC address
@@ -1294,6 +1293,7 @@ static int smsc911x_open(struct net_device *dev)
        smsc911x_reg_write(TX_CFG_TX_ON_, pdata, TX_CFG);

        netif_start_queue(dev);
+       napi_enable(&pdata->napi);
        return 0;
 }

@@ -1302,6 +1302,8 @@ static int smsc911x_stop(struct net_device *dev)
 {
        struct smsc911x_data *pdata = netdev_priv(dev);

+       napi_disable(&pdata->napi);
+
        pdata->stop_link_poll = 1;
        del_timer_sync(&pdata->link_poll_timer);

@@ -1310,7 +1312,7 @@ static int smsc911x_stop(struct net_device *dev)
        netif_stop_queue(dev);

        /* At this point all Rx and Tx activity is stopped */
-       pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
+       dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
        smsc911x_tx_update_txcounters(pdata);

        SMSC_TRACE("Interface stopped");
@@ -1374,8 +1376,8 @@ static struct net_device_stats
*smsc911x_get_stats(struct net_device *dev)
 {
        struct smsc911x_data *pdata = netdev_priv(dev);
        smsc911x_tx_update_txcounters(pdata);
-       pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
-       return &pdata->stats;
+       dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
+       return &dev->stats;
 }

 /* Entry point for setting addressing modes */
@@ -1520,7 +1522,8 @@ static irqreturn_t smsc911x_irqhandler(int irq,
void *dev_id)
                temp = smsc911x_reg_read(pdata, INT_EN);
                temp &= (~INT_EN_RSFL_EN_);
                smsc911x_reg_write(temp, pdata, INT_EN);
-               netif_rx_schedule(dev);
+               /* TODO: Can call netif_rx_schedule_prep here first */
+               netif_rx_schedule(dev, &pdata->napi);
                serviced = IRQ_HANDLED;
        }

@@ -2005,8 +2008,7 @@ static int smsc911x_init(struct net_device *dev)
        dev->set_multicast_list = smsc911x_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
        dev->do_ioctl = smsc911x_do_ioctl;
-       dev->poll = smsc911x_poll;
-       dev->weight = 64;
+       netif_napi_add(dev, &pdata->napi, smsc911x_poll, 64);
        dev->ethtool_ops = &smsc911x_ethtool_ops;

 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2092,12 +2094,12 @@ static int smsc911x_drv_probe(struct
platform_device *pdev)
                retval = -ENOMEM;
                goto out_release_io_1;
        }
-       
-       SET_MODULE_OWNER(dev);
+
        SET_NETDEV_DEV(dev, &pdev->dev);

        pdata = netdev_priv(dev);
-       
+       pdata->netdev = dev;
+
        dev->irq = platform_get_irq(pdev, 0);
        pdata->ioaddr = ioremap_nocache(res->start, res_size);
-
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