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