e1000-7.3.20-kernel-2.6.20.patch
---

Intel PRO/1000 Linux driver
Copyright(c) 1999 - 2007 Intel Corporation.

This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.

This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

The full GNU General Public License is included in this distribution in
the file called "COPYING".

Contact Information:
Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

---

Applies to e1000-7.3.20.

* Fix for INIT_WORK API change in 2.6.20
* Fix for vlan devices array split in 2.6.21rc3

---
General Directions:

This patch applies to e1000-7.3.20 as follows:

$ tar zxf e1000-7.3.20.tar.gz
$ cd e1000-7.3.20
$ patch -p1 < /path/to/e1000-7.3.20-kernel-2.6.20.patch

After applying the patch, rebuild the driver using `make`.

---
 src/e1000_main.c |   23 ++++++++++-------------
 src/kcompat.h    |   31 ++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 14 deletions(-)

---
diff -Nurb e1000-7.3.20/src/e1000_main.c e1000-7.3.20-2.6.20/src/e1000_main.c
--- e1000-7.3.20/src/e1000_main.c	2006-11-27 12:31:38.000000000 -0800
+++ e1000-7.3.20-2.6.20/src/e1000_main.c	2007-03-12 14:27:06.000000000 -0700
@@ -207,7 +207,7 @@
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
 static void e1000_tx_timeout(struct net_device *dev);
-static void e1000_reset_task(struct net_device *dev);
+static void e1000_reset_task(struct work_struct *work);
 static void e1000_smartspeed(struct e1000_adapter *adapter);
 static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
                                        struct sk_buff *skb);
@@ -423,7 +423,7 @@
 	uint16_t vid = adapter->hw.mng_cookie.vlan_id;
 	uint16_t old_vid = adapter->mng_vlan_id;
 	if (adapter->vlgrp) {
-		if (!adapter->vlgrp->vlan_devices[vid]) {
+		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
 			if (adapter->hw.mng_cookie.status &
 				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
 				e1000_vlan_rx_add_vid(netdev, vid);
@@ -433,7 +433,7 @@
 
 			if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
 					(vid != old_vid) &&
-					!adapter->vlgrp->vlan_devices[old_vid])
+			    !vlan_group_get_device(adapter->vlgrp, old_vid))
 				e1000_vlan_rx_kill_vid(netdev, old_vid);
 		} else
 			adapter->mng_vlan_id = vid;
@@ -1128,8 +1128,7 @@
 	adapter->phy_info_timer.function = &e1000_update_phy_info;
 	adapter->phy_info_timer.data = (unsigned long) adapter;
 
-	INIT_WORK(&adapter->reset_task,
-		(void (*)(void *))e1000_reset_task, netdev);
+	INIT_WORK(&adapter->reset_task, e1000_reset_task);
 
 	e1000_check_options(adapter);
 
@@ -1565,7 +1564,7 @@
 	if ((adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
 	     !(adapter->vlgrp &&
-			  adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
+	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
 		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 	}
 #endif
@@ -3576,9 +3575,10 @@
 }
 
 static void
-e1000_reset_task(struct net_device *netdev)
+e1000_reset_task(struct work_struct *work)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_adapter *adapter;
+	adapter = container_of(work, struct e1000_adapter, reset_task);
 
 	e1000_reinit_locked(adapter);
 }
@@ -5126,10 +5126,7 @@
 	uint32_t vfta, index;
 
 	e1000_irq_disable(adapter);
-
-	if (adapter->vlgrp)
-		adapter->vlgrp->vlan_devices[vid] = NULL;
-
+	vlan_group_set_device(adapter->vlgrp, vid, NULL);
 	e1000_irq_enable(adapter);
 
 	if ((adapter->hw.mng_cookie.status &
@@ -5155,7 +5152,7 @@
 	if (adapter->vlgrp) {
 		uint16_t vid;
 		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-			if (!adapter->vlgrp->vlan_devices[vid])
+			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			e1000_vlan_rx_add_vid(adapter->netdev, vid);
 		}
diff -Nurb e1000-7.3.20/src/kcompat.h e1000-7.3.20-2.6.20/src/kcompat.h
--- e1000-7.3.20/src/kcompat.h	2006-11-27 12:31:38.000000000 -0800
+++ e1000-7.3.20-2.6.20/src/kcompat.h	2007-03-12 14:15:23.000000000 -0700
@@ -839,7 +853,10 @@
 
 #include <linux/tqueue.h>
 #define work_struct tq_struct
-#define INIT_WORK INIT_TQUEUE
+#undef INIT_WORK
+#define INIT_WORK(a,b) INIT_TQUEUE(a,(void (*)(void *))b,a)
+#undef container_of
+#define container_of list_entry
 #define schedule_work schedule_task
 #define flush_scheduled_work flush_scheduled_tasks
 
@@ -1099,6 +1137,32 @@
 
 #endif /* < 2.6.19 */
 /*****************************************************************************/
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) )
+#undef INIT_WORK
+#define INIT_WORK(_work, _func) \
+do { \
+	INIT_LIST_HEAD(&(_work)->entry); \
+	(_work)->pending = 0; \
+	(_work)->func = (void (*)(void *))_func; \
+	(_work)->data = _work; \
+	init_timer(&(_work)->timer); \
+} while (0)
+#endif
+
+#ifndef round_jiffies
+#define round_jiffies(x) x
+#endif
+
+#endif /* < 2.6.20 */
+
+/*****************************************************************************/
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
+#ifndef vlan_group_get_device
+#define vlan_group_get_device(vg, id) (vg->vlan_devices[id])
+#define vlan_group_set_device(vg, id, dev) if (vg) vg->vlan_devices[id] = dev;
+#endif
+#endif /* < 2.6.22 */
 
 #endif /* _KCOMPAT_H_ */
 
