Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2377

kernel-2.6.18-238.el5.src.rpm

From: Ivan Vecera <ivecera@redhat.com>
Date: Wed, 23 Jun 2010 08:28:31 -0400
Subject: [net] benet: compat header cleanups, part 2
Message-id: <1277281711.2432.36.camel@ceranb.intra.cera.cz>
Patchwork-id: 26451
O-Subject: Re: [RHEL5 PATCH 1/27] compat.h cleanup: benet driver changes
Bugzilla: 546740

Some corrections are needed (incremental patch to Prarit's one below).

1. RHEL5's poll has to update *budget and also netdev->quota and also
initial value used for polling has to be min(*budget, netdev->quota) and
NOT *budget!
Since upstream NAPI poll func and RHEL5 NAPI poll func are much
different,  IMHO it's better to leave the upstream one untouched and
create for RHEL5 small compat wrapper - overhead is really small and
it's also better for maintaining in future.

2. You are calling netif_rx_schedule/enable/disable with real device as
argument but poll member function ptr is NULL, because be_poll is
assigned to allocated dummy device. This dummy device should not be
allocated and napi->dev should be the real device. This approach was
used for be2net before (see be_compat.c) and also uses r8169 it. The
advantage is also you don't need to change return value of
be_netdev_init to 'int' and to solve the problem with dummy net device
allocation failure.

Ivan


diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 8c54003..e38b602 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1410,9 +1410,10 @@ int be_poll_tx(struct be_adapter *adapter, int budget)
 	return num_cmpl;
 }
 
-int be_poll(struct net_device *dev, int *budget)
+int be_poll(struct napi_struct *napi, int budget)
 {
-	struct be_adapter *adapter = netdev_priv(dev);
+	struct be_adapter *adapter =
+				container_of(napi, struct be_adapter, napi);
 	struct be_eq_obj *eq_obj = &adapter->be_eq;
 	u16 num = 0;
 	u32 tx_work, rx_work;
@@ -1420,15 +1421,15 @@ int be_poll(struct net_device *dev, int *budget)
 	while (event_get(eq_obj))
 		num++;
 
-	tx_work = be_poll_tx(adapter, *budget);
-	rx_work = be_poll_rx(adapter, *budget);
+	tx_work = be_poll_tx(adapter, budget);
+	rx_work = be_poll_rx(adapter, budget);
 	be_process_mcc(adapter);
 
 	drvr_stats(adapter)->be_num_events += num;
 
 	/* All consumed */
-	if (rx_work < *budget) {
-		napi_complete(&adapter->napi);
+	if (rx_work < budget) {
+		napi_complete(napi);
 		be_eq_notify(adapter, eq_obj->q.id, true, false, num);
 	} else
 		be_eq_notify(adapter, eq_obj->q.id, false, false, num);
@@ -1436,6 +1437,20 @@ int be_poll(struct net_device *dev, int *budget)
 	return rx_work;
 }
 
+static int be_poll_compat(struct net_device *netdev, int *budget)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	u32 work_done, can_do;
+
+	can_do = min(*budget, netdev->quota);
+	work_done = be_poll(&adapter->napi, can_do);
+
+	*budget -= work_done;
+	netdev->quota -= work_done;
+
+	return (work_done < can_do) ? 0 : 1;
+}
+
 static void be_worker(void *data)
 {
 	struct work_struct *work = data;
@@ -1978,10 +1993,9 @@ fw_exit:
 	return status;
 }
 
-static int be_netdev_init(struct net_device *netdev)
+static void be_netdev_init(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct net_device *napi_nd;
 
 	netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
 		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
@@ -2011,20 +2025,12 @@ static int be_netdev_init(struct net_device *netdev)
 
 	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
 
-	napi_nd = alloc_netdev(0, "", ether_setup);
-	if (!napi_nd)
-		return -ENOMEM;
-
-	napi_nd->priv = adapter;
-	napi_nd->weight = BE_NAPI_WEIGHT;
-	napi_nd->poll = be_poll;
-	set_bit(__LINK_STATE_START, &napi_nd->state);
-	adapter->napi.dev = napi_nd;
+	netdev->weight = BE_NAPI_WEIGHT;
+	netdev->poll = be_poll_compat;
+	adapter->napi.dev = netdev;
 
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
-
-	return 0;
 }
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
@@ -2211,9 +2217,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
 
 	be_ctrl_cleanup(adapter);
 
-	free_netdev(adapter->napi.dev);
-	adapter->napi.dev = NULL;
-
 	be_msix_disable(adapter);
 
 	pci_set_drvdata(pdev, NULL);
@@ -2286,8 +2289,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	adapter->pdev = pdev;
 	pci_set_drvdata(pdev, adapter);
 	adapter->netdev = netdev;
-	if (be_netdev_init(netdev))
-		goto rel_drvdata;
+	be_netdev_init(netdev);
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
 	be_msix_enable(adapter);
@@ -2353,11 +2355,8 @@ stats_clean:
 ctrl_clean:
 	be_ctrl_cleanup(adapter);
 free_netdev:
-	free_netdev(adapter->napi.dev);
-	adapter->napi.dev = NULL;
 	be_msix_disable(adapter);
 	free_netdev(adapter->netdev);
-rel_drvdata:
 	pci_set_drvdata(pdev, NULL);
 rel_reg:
 	pci_release_regions(pdev);