lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 28 Nov 2007 17:51:24 +0000
From:	"Bahadir Balban" <bahadir.balban@...il.com>
To:	netdev@...r.kernel.org
Subject: smsc911x changes for new NAPI

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 majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists